diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..c92d4c8bdb --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +--- +github: [pgmodeler] +custom: ["https://pgmodeler.io/#donationForm"] diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md new file mode 100644 index 0000000000..4d054a0f2e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -0,0 +1,38 @@ +--- +name: Report a bug +about: Instructions on how to report pgModeler bugs. Before report any bug please + check if someone already has submited issues similiar to yours. Duplicated issues + will be ignored. + +--- + +**Bug description** +_A clear and concise description of what the bug is._ + +**How to reproduce** +_Please, if the bug can be reproduceable describe the steps in full details. If possible provide a sample model and/or a SQL dump for test purposes._ + +**Expected behavior** +_A clear and concise description of what you expected to happen._ + +**Screenshots** +_If applicable, add screenshots to help explain your problem._ + +**Info about your desktop** + - OS: + - Version: + - Window manager: + - pgModeler version: + - Qt version: + +**Stacktrace / Debug info** +_If pgModeler crashed after the bug raised attach the stacktrace below_ + +``` + + Put the stacktrace here! + +``` + +**Additional info** +_Add any other information that you may find useful to help in the problem solving._ diff --git a/.github/ISSUE_TEMPLATE/Custom.md b/.github/ISSUE_TEMPLATE/Custom.md new file mode 100644 index 0000000000..219c04f5c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Custom.md @@ -0,0 +1,8 @@ +--- +name: General discussion +about: For any discussion not related to bugs or feature requests please use this + one. + +--- + + diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md new file mode 100644 index 0000000000..f3ad5eb15b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request / improvement +about: Give your suggestions for improvements to this project. + +--- + +**Feature description** +_A clear and concise description of what the problem is._ + +**Sample image** +_If the feature requested is a visual improvement, please, attach some images to make it clear._ + +**Additional info** +_Add any other context or screenshots about the feature request here._ diff --git a/.github/workflows/linuxbuild.yml b/.github/workflows/linuxbuild.yml new file mode 100644 index 0000000000..36fb2d71d5 --- /dev/null +++ b/.github/workflows/linuxbuild.yml @@ -0,0 +1,34 @@ +name: Linux build + +on: + push: + branches: [ main, develop, 1.* ] + tags: 1.* + + pull_request: + branches: [ main, develop, 1.* ] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + qt: ['6.2.4', '6.3.2', '6.4.3', '6.5.1'] + + steps: + - uses: actions/checkout@v2 + + - name: Installing Qt framework + uses: jurplel/install-qt-action@v3 + with: + version: ${{ matrix.qt }} + + - name: Running qmake + run: cd $GITHUB_WORKSPACE; qmake pgmodeler.pro -r PREFIX=$GITHUB_WORKSPACE/build CONFIG+=debug + + - name: Building pgModeler + run: make -j6 + + - name: Deploying pgModeler + run: make install diff --git a/.github/workflows/macosbuild.yml b/.github/workflows/macosbuild.yml new file mode 100644 index 0000000000..3b047bfa04 --- /dev/null +++ b/.github/workflows/macosbuild.yml @@ -0,0 +1,34 @@ +name: macOs build + +on: + push: + branches: [ main, develop, 1.* ] + tags: 1.* + + pull_request: + branches: [ main, develop, 1.* ] + +jobs: + build: + runs-on: macos-latest + + strategy: + matrix: + qt: ['6.2.4', '6.3.2', '6.4.3', '6.5.1'] + + steps: + - uses: actions/checkout@v2 + + - name: Installing Qt framework + uses: jurplel/install-qt-action@v3 + with: + version: ${{ matrix.qt }} + + - name: Running qmake + run: cd $GITHUB_WORKSPACE; qmake pgmodeler.pro -r PREFIX=/Applications/pgModeler.app/Contents PGSQL_INC=`pg_config --includedir` PGSQL_LIB=`pg_config --libdir`/libpq.dylib CONFIG+=debug + + - name: Building pgModeler + run: make -j6 + + - name: Deploying pgModeler + run: make install diff --git a/.github/workflows/windowsbuild.yml b/.github/workflows/windowsbuild.yml new file mode 100644 index 0000000000..a5bc994dd4 --- /dev/null +++ b/.github/workflows/windowsbuild.yml @@ -0,0 +1,48 @@ +name: Windows build + +on: + push: + branches: [ main, develop, 1.* ] + tags: 1.* + + pull_request: + branches: [ main, develop, 1.* ] + +jobs: + build: + runs-on: windows-latest + + strategy: + matrix: + qt: ['6.x'] + + defaults: + run: + shell: msys2 {0} + + steps: + - uses: actions/checkout@v2 + + - uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: base-devel mingw-w64-x86_64-make mingw-w64-x86_64-clang mingw-w64-x86_64-postgresql mingw-w64-x86_64-qt6 + + # Workaround: Instead of using $GITHUB_WORKSPACE in PREFIX we actually use the path converted to unix-like + # since we're running the building inside msys2 + - name: Running qmake + run: | + cd $GITHUB_WORKSPACE; + qmake-qt6 pgmodeler.pro -spec win32-clang-g++ -r PREFIX=D:/a/pgmodeler/pgmodeler/build \ + XML_INC=$(cygpath -m /mingw64/include/libxml2) \ + XML_LIB=$(cygpath -m /mingw64/bin/libxml2-2.dll) \ + PGSQL_INC=$(cygpath -m /mingw64/include) \ + PGSQL_LIB=$(cygpath -m /mingw64/bin/libpq.dll) \ + CONFIG+=debug + + - name: Building pgModeler + run: mingw32-make -j6 + + - name: Deploying pgModeler + run: mingw32-make install diff --git a/.gitignore b/.gitignore index ca413d0a72..028dc0e5c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,58 @@ +.qmake.stash + *.[oa] +*.dll +*.exe *.so.* *.so -ui_*.h -moc_*.cpp -obj/* -moc/* -Makefile -build/* +*.dylib *.pro.user *.directory *.run +*.Debug +*.Release +*.old + +moc_*.cpp +moc_*.h +qrc_resources.cpp +ui_*.h +windeploy.log +Makefile + +build/* +dist/* +moc/* +obj/* +plugins +plugins/* +priv-plugins +priv-plugins/* +release/* +apps/pgmodeler-se/pgmodeler-se +apps/pgmodeler/pgmodeler +apps/pgmodeler-ch/pgmodeler-ch +apps/pgmodeler-sc/pgmodeler-sc +apps/pgmodeler-cli/pgmodeler-cli +tests/src/main/runtests +tests/src/basefunctiontest/basefunctiontest +tests/src/databasemodeltest/databasemodeltest +tests/src/servertest/servertest +tests/src/proceduretest/proceduretest +tests/src/csvparsertest/csvparsertest +tests/src/foreigndatawrappertest/foreigndatawrappertest +tests/src/schemafilessyntaxtest/schemafilessyntaxtest +tests/src/syntaxhighlightertest/syntaxhighlightertest +tests/src/linenumberstest/linenumberstest +tests/src/testkeywordquotes/Makefile +tests/src/testkeywordquotes/testkeywordquotes +tests/src/baseobjecttest/baseobjecttest +tests/src/roletest/roletest +tests/src/fileselectortest/fileselectortest +tests/src/schemaparsertest/schemaparsertest +tests/src/partrelationshiptest/baseobjecttest +tests/src/partrelationshiptest/partrelationshiptest +tests/src/xmlparsertest/xmlparsertest +tests/src/datadicttest/datadicttest +tests/src/usermappingtest/usermappingtest +tests/src/transformtest/transformtest diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ac057b6c7..be1791005b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,1716 @@ -Change Log +Changelog --------- +v1.1.0-alpha1 +------ +Release date: September 29, 2023
+ +* [New] Added version descriptor for PostgreSQL 16. +* [New] Added support for highlighting table child objects in ObjectFinderWidget. +* [New] Added the method BaseTableView::setChildSelected. +* [New] Added support for resizing the text boxes in the model using Shift + mouse movement. +* [New] Created the method generateHashCode in TableObject and its derived classes. +* [New] Added the method BaseObject::getLinkedObjects. +* [New] Added the method AppearanceConfigWidget::getUiLightness. +* [New] Created the utility function CoreUtilsNs::filterObjectsByType. +* [New] Added the method BaseObject::setClearDepsInDtor to determine whether the dependencies/references should be undone when destroying an object. +* [New] Created a simplified mechanism for mapping dependencies and references between objects improving the performance of several parts of the tool. +* [New] Created the function UtilsNs::getStringHash and replaced all uses of QCryptographicHash by that function. +* [New] Added an option to ObjectDepsRefsWidget that toggles the display of unique results. +* [New] Created the class CustomSortProxyModel that preserves the vertical header line number when sorting an ObjectsListModel. +* [New] Created the method GuiUtilsNs::updateObjectsTable(QTableView *, std::vector). +* [New] Created the method ObjectsListModel::fillModel. +* [New] Added the methods BaseObject::getSearchAttributeI18N and BaseObject::getSearchAttributesI18N. +* [New] Added the method BaseObject::acceptsComment. +* [New] Added support for caching the object names to avoid unnecessary formatting/validation. +* [New] Added the method BaseGraphicObject::setUpdatesEnabled to control whether the *::configureObject must be called to configure the graphical objects. +* [New] Added support for inksaver color theme. +* [New] Added support for using object comments as aliases in database import. +* [New] Added an option in GeneralConfigWidget to reset the exit alert display status. +* [New] Added the method GeneralConfigWidget::appendConfigurationSection. +* [New] Created the class ObjectsListModel to be used by any QTableView that is supposed to display objects listing. +* [New] Add support for remembering decisions on the alerts regarding unsaved models/open SQL tabs. +* [New] Added the method SQLToolWidget::ignoreAutoBrowseFlag. +* [New] Added the method SQLExecutionWidget::getSQLCommand. +* [New] Added the methods SQLToolWidget::getExecutionTabs. +* [New] pgModeler now asks the user about closing SQL execution tabs that are not empty (with typed commands). +* [New] Added a basic form to inspect changelog XML code. +* [New] Added a static method AppearanceConfigWidget::getUiThemeId that returns the current configured theme. +* [New] Added missing multirange types. +* [New] Added shortcuts Shift+Up and Shift+Down to control the Z-stack operations in ModelWidget. +* [Change] Adjusted the objects' movement using arrow keys in the object scene. +* [Change] Adjusted the PostgreSQL Version to 15 in pgmodeler.pri (only macos). +* [Change] Minor adjustment in ModelDatabaseDiffForm to exclude columns when using "any" filter. +* [Change] Replaced the use of DatabaseModel::getObjectReferences by BaseObject::getReferences +* [Change] All objects' dependencies/references retrieval methods were removed from DatabaseModel due to the new way to control/retrieve dependencies/references via the BaseObject class. +* [Change] Refactored DatabaseImportHelper::destroyDetachedColumns to use BaseObject::getReferences. +* [Change] Removed the method DatabaseModel::validateColumnRemoval. +* [Change] Changed DatabaseModel::__removeObject to use the new BaseObject::getReference. +* [Change] Changed ModelValidationHelper::validateModel to use BaseObject::getReference. +* [Change] Changed ModelWidget::copyObjects to use BaseObject::getDependencies. +* [Change] Minor adjustment in ModelWidget destructor. +* [Change] Minor adjustment in DatabaseModel destructor. +* [Change] Adjusted several virtual methods signatures. +* [Change] Refactored UserTypeConfig and PgSqlType to make use of BaseObject/DatabaseModel pointers instead of raw (void) pointers to configure user-defined types based on database model objects. +* [Change] Adjusted the font size for layer rects. +* [Change] Minor adjustment in DatabaseModel::validateSchemaRenaming. +* [Change] Improved the relationship point addition via mouse clicks. +* [Change] Minor adjustment in DatabaseModel::setObjectsModified. +* [Change] The "dot" grid mode is now the default in the appearance.conf file due to better drawing performance. +* [Change] Created a mechanism in Relationship to reuse allocated objects instead of deleting them and allocating them again every time the relationship is connected/disconnected. +* [Change] Improved the scene background (grid, delimiter, limits) drawing speed for big models. +* [Change] Refactored DatabaseImportForm in such a way as to use QTableView instead of QTableWidget to list filter results. +* [Change] Refactored ModelDatabaseDiffForm in such a way as to use QTableView instead of QTableWidget to list filter results. +* [Change] Minor adjustment in ObjectsListModel to accept a list of attributes map to fill the table model. +* [Change] Refactored SwapObjectsIdsWidget in such a way as to use QTableView instead of QTableView. +* [Change] Refactored ObjectDepsRefsWidget by replacing QTableWidget with QTableView to display model objects. +* [Change] Minor adjustment in ObjectFinderWidget filter items order. +* [Change] Minor adjustment in GuiUtilsNs::updateObjectsTable(QTableView *) to create a QSortFilterProxyModel in the QTableView allowing sorting. +* [Change] Refactored ObjectFinderWidget to use QTableView instead of QTableWidget to display search results. +* [Change] Removed the QTableWidget instance in ModelObjectsWidget for performance reasons and for being a widget almost unused. +* [Change] Minor adjustment in BaseRelationship::connectRelationship. +* [Change] Adjusted BaseObjectWidget::applyConfiguration to avoid crashing when the general attributes of the widget are in a non-visible tab like in TableWidget. +* [Change] Reduced the number of times BaseGraphicObject::setModified is called consequently reducing the excessive objects' rendering. +* [Change] Minor adjustment in ObjectsScene::drawBackground to avoid rendering the grid and page delimiters during corner/scene move. +* [Change] Moved the table's general attributes to a dedicated tab which opened more space for displaying columns and other children's objects. +* [Change] Refactored GuiUtilsNs::updateObjectTable to accept a QTableView instead of QTableWidget. +* [Change] Updated the pgmodeler-cli menu to include the "any" filter explanation. +* [Change] Removed the plugin's configuration menu from the main toolbar. +* [Change] Improving the objects' filtering in reverse engineering by adding an "any" filter type. +* [Change] Minor adjustment on SQLToolWidget +* [Change] Improved the import error message when it's not possible to create/import permission that references a predefined PostgreSQL role. +* [Change] Minor improvement on ChangelogWidget layout. +* [Change] Minor code refactor in ObjectsScene and DatabaseModel. +* [Change] DataManipulationForm now shows a confirmation message before closing when items are pending save. +* [Change] Moved the method AppearanceConfigWidget::updateDropShadows to GuiUtilsNs::updateDropShadows +* [Change] Refactored the usage of AppearanceConfigWidget::updateDropShadows to use GuiUtilsNs::updateDropShadows +* [Change] Minor adjustments in swapobjectsidswidget.ui layout. +* [Change] Several minor widget adjustments. +* [Change] Renamed the methods startPanningMove and finishPanningMove to, respectively, startSceneMove and finishSceneMove. +* [Fix] Minor fix in ObjectFinderWidget to avoid disconnecting a null selection model in findObjects. +* [Fix] Minor fix in ModelWidget to hide new objects overlay when moving a selection of objects. +* [Fix] Minor fix in GuiUtilsNs::disableObjectSQL. +* [Fix] Minor fix in RelationshipView::configureBoundingRect and RelationshipView::configureLine. +* [Fix] Minor fix in ModelWidget::removeObjects that was not erasing an object in case it shared the same name or other objects in the same schema. +* [Fix] Minor fix in DatabaseModel::__addObject that validates the layer of the object being added. If one or more layers are invalid the object will be moved to the default layer 0 +* [Fix] Fixed the bounding rect calculation for RelationshipView. +* [Fix] Fixed a bug in DatabaseModel::findObject that was not parsing correctly the search filters with the "any" keyword. +* [Fix] Fixed the icons-*.conf to include QTableView class. +* [Fix] Minor fix in PgModelerCliApp::extractObjectXML to restore correctly the layers name/count. +* [Fix] Fixed a bug in partial reverse engineering that was not correctly importing functions in some specific conditions. +* [Fix] Fixed a bug in partial reverse engineering that was not importing some dependencies correctly. +* [Fix] Fixed a bug in AppearanceConfigWidget that was not updating the example model colors when changing the UI theme. +* [Fix] Fixed a crash when double-clicking the overview widget. +* [Fix] Fixed data dictionaries schema files for tables and views. +* [Fix] Fixed a bug in DatabaseModel that was causing FK relationships of a hidden layer to be displayed after loading the model. +* [Fix] Fixed a bug in MainWindow that was causing the plugin's config action icon to disappear when triggering validation. +* [Fix] Fixed the headers inclusion chain in all subproject sources. +* [Fix] Fixed a bug in scene move that was causing the grid to not be displayed after a panning/wheel move. + +v1.0.5 +------ +Release date: July 26, 2023
+ +* [New] Added shortcuts to Z-stack operations in ModelWidget. +* [New] Added missing PostgreSQL multirange types +* [Change] Improved the import error message when it's not possible to create/import a permission which references a predefined PostgreSQL role. +* [Change] Minor code refactor in ObjectsScene and DatabaseModel. +* [Fix] Fixed Qt 6.2 release in linuxbuild.yml and macosbuild.yml. +* [Fix] Fixed a bug in DatabaseModel that was causing FK relationships of a hidden layer to be displayed after loading the model. +* [Fix] Fixed a bug in MainWindow that was causing the plugins config action icon to disappear when triggering validation. +* [Fix] Fixed a bug in PgModelerCliApp::fixModel that was causing the generation of empty models when the input file had no tag . + +v1.1.0-alpha +------ +Release date: June 09, 2023
+ +* [New] Added support for drag & drop files in the main window to load models. +* [New] Added NOBYPASSRLS keyword to sql-highlight.conf. +* [New] Added OS type information in AboutWidget. +* [New] Added support for hiding objects' shadows in the settings. +* [New] Added support for installing tool buttons created by plugins in DatabaseExplorerWidget. +* [New] Added support for code completion based on living database object names in CodeCompletionWidget. It is now possible to list column/table names in the middle of the INSERT/DELETE/TRUNCATE/UPDATE commands. +* [New] Added support for exporting results in CSV and plain text format in DataManipulationForm and SQLExecutionWidget. +* [New] Added support for highlighting enclosing characters (),{},{} in SyntaxHighlighter. +* [New] Added the action NumberedTextEditor::pasteCode which tries to remove unneeded string concatenation chars ", ', + and . in the clipboard text before inserting it in the input field. This is useful for developers that copy SQL code in the middle of a programming language source code and want to test it in the database. +* [New] Added the button id Messagebox::CloseButton that creates a message box with only a close button. +* [New] Added the class CustomUiStyle to control global settings for pixel metrics of UI elements. +* [New] Added the method BaseForm::adjustMinimumSize. +* [New] Added the method CodeCompletionWidget::setConnectionParams. +* [New] Added the method PgModelerPlugin::getTmplPluginFilePath. +* [New] Added the methods setFileMustExist, setCheckExecutionFlag, setFileIsMandatory, and setNamePattern to FileSelectorWidget. +* [New] Added the options in GeneralConfigWidget that controls the column data truncation in the results grid. +* [New] Added support for setup name color of schema objects. +* [New] Added support to convert to XML entities the characters in attribute values in SchemaParser. +* [New] Added support for switching the current user when successfully connecting to a database via SET ROLE command. +* [New] Created the method DatabaseImportForm::listDatabases(Connection,QComboBox). +* [New] Enabling the displaying of byta column data in the results grid. +* [New] Now any SQL result grid header will display an icon according to the data type of each column. +* [New] Removed the method FileSelectorWidget::setFileMode and created to FileSelectorWidget::setDirectoryMode that toggles the selection of directories instead of files (the default behavior). +* [Change] Minor adjustment in FileSelectorWidget::validateSelectedFile. +* [Change] Added a wait cursor during the code preview in SourceCodeWidget. +* [Change] Added a wait cursor while searching objects in ObjectFinderWidget. +* [Change] Adjusted the access modifier in PgModelerPlugin methods. +* [Change] Adjusted the object catalog queries to include a general-purpose field named extra_info in the object list catalog query. +* [Change] Adjusted the warning icon size in FileSelectorWidget. +* [Change] Disabled the usage of keywords in the code completion instance of DataManipulationForm filter field. +* [Change] Dropped the use of syntax-hl-theme in appearance.conf. +* [Change] Improved the behavior of the "System default" UI theme. +* [Change] Improved the methods GuiUtilsNs::selectAndSaveFile, GuiUtilsNs::selectAndLoadFile. +* [Change] Improvements in LineNumbersWidget and NumberedTextEditor to correctly draw line numbers on text with the word wrap option activated. +* [Change] In data manipulation form when editing a single element with column data edit dialog, the form will display the current column's value. +* [Change] Change to medium the UI icons size of default settings. +* [Change] Minor adjustment in aboutsewidget.ui and aboutwidget.ui. +* [Change] Minor adjustment in the minimum size of Messagebox. +* [Change] Minor adjustment in Catalog::isConnectionValid. +* [Change] Minor adjustment in file coreutilsns.cpp. +* [Change] Minor adjustment in ModelFixForm to display pgmodeler-cli selector when the provided path to the executable is not valid. +* [Change] Minor adjustment in generalconfigwidget.ui. +* [Change] Minor adjustment in ObjectFinderWidget. +* [Change] Minor adjustment in schemaeditorform.ui. +* [Change] Minor refactor in TableObjectView, Connection, SchemaParser. +* [Change] Moved the copy actions in SQL results grid context menu to an action named the "Selection" in the same menu. +* [Change] Now the ColumnDataEditWidget instances have their geometry saved/restored. +* [Change] Replace the QPlainTextEdit by NumberedTextEditor in ColumnDataWidget. +* [Change] Refactored DatabaseImportHelper::createObject in such a way to use a map of bind methods to perform operations instead of using a long list of switch/case to determine which method must be called to create the object during reverse engineering. +* [Change] Refactored DatabaseModel::createObject, DatabaseModel::addObject, and DatabaseModel::removeObject in such a way to use a map of bind methods to perform operations instead of using a long list of if/else to determine which method must be called. +* [Change] Removed the get*Action and getDbExplorerButton methods in PgModelerPlugin and created the methods getAction and getWidget instead. +* [Change] Removed the method Catalog::getObjectCount(bool) and created a version that accepts a list of object types. +* [Change] Removed unneeded use of QString(""). +* [Change] Removed unused frame in modelfixform.ui. +* [Change] Renamed BulkDataEditWidget to ColumnDataWidget +* [Change] Replaced QApplication::setOverrideCursor/restoreOverrideCursor by qApp- >setOverrideCursor/restoreOverrideCursor. +* [Change] The method DatabaseExplorerWidget::addPluginToolButton passes the current connection id and database name as the plugin button property to be read in the click/triggered slots implemented in the plugin. +* [Change] Update all schema files that generate XML code to use &{} attribute form where there's the need to convert chars to their XML entities counterparts. +* [Change] When retrieving objects from the database CodeCompletionWidget will not display keywords and snippets in the popup list. +* [Fix] Addition fix in CodeCompletionWidget in such a way to preserve cursor position when inserting the selected word after a special char. +* [Fix] Fix a bug in PgModelerCliApp::fixModel that was causing the generation of empty models when the input file had no tag +* [Fix] Fixed a bug in Catalog::getObjectsCount. +* [Fix] Fixed a bug in DatabaseModel that could lead to an "unknown exception caught" error. +* [Fix] Fixed a bug in NumberedTextEditor::identSelection. +* [Fix] Fixed a bug in SqlExecutionWidget::fillResultsTable. +* [Fix] Fixed a bug in TableDataWidget::generateDataBuffer that was causing the generation of malformed CSV in some circumstances. +* [Fix] Fixed a crash in the SQL tool when closing a database explorer instance that owns a plugin tool button. +* [Fix] Fixed CodeCompletionWidget::retrieveColumnNames when referencing a table via an alias. +* [Fix] Fixed problems with comments on a database having the same OIDs of different types of objects +* [Fix] Fixed the diff process on legacy database versions. +* [Fix] Fixed the line selection operation in LineNumbersWidget. +* [Fix] Fixed the undefined reference error when building on Windows. +* [Fix] Minor fixes in the catalog queries for column, cast, collation, and role. +* [Fix] Minor fix in GeneralConfigWidget when using NO_UPDATE_CHECK. +* [Fix] Minor fix in process output capturing in ModelFixForm. +* [Fix] Minor tooltip fix in DataManipulationForm. + +v1.0.4 +------ +Release date: May 19, 2023
+ +* [New] Now pgModeler selects the UI element colors based upon the system's default colors set (light/dark). +* [New] pgModeler now restores the default settings in case of some configuration file is corrupted/incompatible and causes the initialization to fail. +* [New] Allowing sequences to be assigned to columns with numeric type. +* [New] Created the methods GuiUtilsNs::saveFile and GuiUtilsNs::loadFile. +* [Change] Removed the deprecated attribute partial-match from configuration files in conf/defaults. +* [Change] Minor adjustment in output messages in PgModelerCliApp::createConfigurations. +* [Change] SyntaxHighlighter when in single-line mode will strip any line break char in the input field. +* [Change] Minor adjustment in SyntaxHighlighter to force no line wrap in the parent input when single_line_mode is activated. +* [Change] Changed the behavior of TableDataWidget::populateDataGrid. Instead of failing and never opening the dialog again for the user to try to import another file, the method now ask for saving the current (corrupted data) to a file and opens an empty grid to a new CSV import. +* [Change] Removed unused constant PhysicalTable::DataLineBreak. +* [Fix] Fixed a false-positive diff result when comparing numeric columns. +* [Fix] Minor fix in the name pattern of the settings backup folder in PgModelerCliApp::createConfigurations. +* [Fix] Fixed bug in reverse engineering that was happening during the creation of object permissions. +* [Fix] Minor fixes in the catalog queries for cast, collation, and role. +* [Fix] Fixed the wrong usage of cached names and signatures in DatabaseImportHelper. +* [Fix] Additional fix in CsvParser::parseBuffer to append a line break character at the end of the buffer in case it is missing so the parsing can be done correctly. + +v1.0.3 +------ +Release date: April 24, 2023
+ +* [New] pgmodeler-cli now logs objects that fail to be recreated in fix process into a log file stored in pgModeler's temp directory. +* [New] Added a progress bar to model fix form and a cancel button which allows aborting the fix operation without close that form. +* [New] Added a specific icon for CSV load button in CsvLoadWidget. +* [New] Added the methods Trigger::getColumns and Trigger::addColumns. +* [Change] Adjusted the behavior of hide and close events of model fix form. +* [Change] Minor adjustment in pgmodeler-cli model fix messages. +* [Change] Refactored TriggerWidget to use an instance of ColumnPickerWidget. +* [Fix] Fixed the database model file header validation for huge models in pgmodeler-cli. +* [Fix] Fixed a bug in TableDataWidget::generateDataBuffer that was causing the generation of malformed CSV in some circumstances. +* [Fix] Fixed the PluginsConfigWidget::initPlugins in such a way to remove the plugins that failed to load from the plugins grid. +* [Fix] Fixed a bug in BaseRelationship::canSimulateRelationship11 that was wrongly returning true. + +v1.0.2 +------ +Release date: March 14, 2023
+ +* [Fix] Fixed a bug related to importing referenced tables of FKs in partial import mode. +* [Fix] Fixed the attributes toggler item border style in partition tables. +* [Fix] Fixed a regression that was preventing the canvas color to be changed. +* [Fix] Fixed a bug in BaseObjectWidget::finishConfiguration that was preventing the creation of a role and a table with the same names. +* [Fix] Fixed the generation of DROP command for policy, trigger, and rule. +* [Fix] Fixed a bug that was causing objects to be selected in the sample model at appearance settings. +* [Fix] Forcing the usage of Qt 6.x due to problems on Windows when compiling with Qt 5. +* [Fix] Minor adjustment in CodeCompletionWidget stylesheet. +* [Fix] Saving/restoring the painter settings after drawing the background in ObjectsScene. +* [Fix] Fixed a malformed diff code for policies. + +v1.0.1 +------ +Release date: February 17, 2023
+ +* [New] AppearanceConfigWidget now adjusts the drop shadows on tool buttons according to the current theme. +* [Change] pgModeler will now ask for PK columns uncheck when removing a primary key in the Constraints tab at TableWidget +* [Change] Disabling catalog query for transform objects in PG9.x +* [Change] Improving the visibility of some elements in QMenu and AboutWidget +* [Fix] Fixed the assignment of layer colors when loading the model in compatibility mode. +* [Fix] Minor fix in ModelWidget::toggleSchemasRectangles +* [Fix] Fixed the disable state change for delimiter scale lock action when changing the current main window view. +* [Fix] Fixed the method FileSelectorWidget::openFileExternally. + +v1.0.0 +------ +Release date: February 1, 2023
+ +* [New] Added an option in GeneralConfigWidget to allow pgModeler to connect to older PostgreSQL server versions, below 10 using a minimum (not reliable) compatibility mode. +* [New] Added an option to change ObjectsScene grid pattern. Available options are square and dot. +* [New] Added an option to lock the page delimiters resize during zoom out (<100%) to allow the user to place more objects on one page. +* [New] Added the ability to print models with a specified scale factor. +* [New] Added the method MainWindow::updateWindowTitle. +* [New] Created the method ObjectsTableWidget::setRowColors. +* [New] Added the public slot ObjectsTableWidget::resizeContents. +* [New] Added the signal MainWindow::s_modelLoadRequested. +* [New] Added the method PgModelerPlugin::postInitPlugin which is called when the main window initialization is ready. +* [New] Added the method MainWindow::registerRecentModel. +* [New] Added the method PgModelerPlugin::getPluginFilePath. +* [New] Created the method DatabaseModel::setDatabaseModelAttributes. +* [New] Added the class ObjectTypesListWidget that implements a QListWidget specialization for object types handling. +* [New] Added the method PgModelerPlugin::getPluginIconPath. +* [New] Added the method MainWindow::getCurrentModel. +* [Change] Minor adjustment in the factor applied to delimiter lines in ObjectsScene::setGridSize. +* [Change] Minor tooltip adjustment in generalconfigwidget.ui +* [Change] pgModeler now allows to import and diff in PostgreSQL versions below 10 using the minimum compatibility mode without guaranteeing reliable results. +* [Change] Moved the Q_DECLARE_METATYPE macro call to the header files of classes that use it. +* [Change] Dropped outdated UI translations. +* [Change] Minor adjustment in ModelWidget::printModel to hide scene boundary lines when printing model. +* [Change] Minor adjustment in ObjectsScene::finishObjectsMove and ModelWidget::adjustSceneSize to give extra size to the scene rectangle. +* [Change] The scene rectangle is now always resized to the current objects' bounding rectangle. +* [Change] Overloaded the method QGraphicsScene::drawBackground in ObjectsScene to draw the grid, page delimiters, and scene limits instead of using pixmap-based background. +* [Change] Minor adjustment in the plugins' actions in the toolbar. +* [Change] Minor adjustment in the data retrieving message in DataManipulationForm. +* [Change] Allowing plugins to insert actions in the top toolbar at the main window via PgModelerPlugin::getToolbarAction. +* [Change] Replaced the object type filter in ModelObjectsWidget with an instance of ObjectTypesListWidget. +* [Change] Moved the method ObjectFinderWidget::updateObjectTable to GuiUtilsNs. +* [Change] Minor refactor by replacing hardcoded references to .dbm extension by GlobalAttributes::DbModelExt. +* [Change] Changed the location where the MainWindow::s_modelSaved signal is emitted. +* [Change] Minor adjustment in the plugin's info dialog. +* [Change] Minor adjust in icons CSS. +* [Change] Changed the position of the recent model actions. +* [Change] Minor adjustment in mainwindow.ui. +* [Change] Minor refactor in MainWindow and WelcomeWidget. +* [Change] Removed the overloaded version of getSignature from Trigger, Policy, and Rule. +* [Change] Minor adjust in pgmodeler.pri. +* [Change] Replaced the clunky filter options in ObjectFinderWidget with a menu action associated with the "Filter" button. +* [Change] Changed the behavior of DatabaseModel::findObjects. Now it treats BaseRelationship and Relationship as the same object type to make the search results more accurate. +* [Change] Renamed some GlobalAttributes consts *Dir to *Path for a better semantics. +* [Change] Removed unused variable in DatabaseModel::findObjects. +* [Change] Adjusted Constraint::configureSearchAttributes to create a "signature" attribute in the form schema.table.name. +* [Change] Changed getPluginIconPath to retrieve icons from .qrc file instead of from the filesystem. +* [Change] Minor improvement in HtmlItemDelegate. Now one can construct this object by opting to ignore the HTML tags in sizeHint calculation. +* [Change] Refactored PgModelerPlugin by removing methods hasMenuAction, hasConfigurationForm, and getPluginShortcut. +* [Change] Refactored PluginsConfigWidget::installPluginsActions to receive only a QMenu instance. +* [Change] Removed MainWindow::executePlugin slot since the plugin execution must be triggered by the plugin itself via menu action or model action. +* [Change] Minor improvement in PluginsConfigWidget to force the unloading of plugins that do not meet a version requirement. +* [Fix] Fixed a bug in ModelOverviewWidget that was causing generated pixmap to be blurry on hi-dpi screens. +* [Fix] Fixed a crash when the user tried to browse a DB in PostgreSQL 15. +* [Fix] Fixed how printer settings are changed compared to the default one and triggers a message box so the user can decide which conf to use. +* [Fix] Fixed the use of zoom factor in the PNG export process. +* [Fix] Fixed the ConnectionsConfigWidget::handleConnection alias desambiguation routine. +* [Fix] Minor fix in the BaseForm::setButtonConfiguration signature. +* [Fix] Fixed a bug that was causing relationship name patterns to be loaded in the wrong order. +* [Fix] Fixed the generation of the COMMENT command for constraints. +* [Fix] Fixed the class ObjectTypesListWidget by adding __libgui directive (Windows only). +* [Fix] Minor fix in HtmlItemDelegate to display text in the correct position. +* [Fix] Minor fix in CodeCompletionWidget. +* [Fix] Fixed a bug in the generation of the ALTER OWNER command for materialized views. +* [Fix] Minor fix in ObjectRenameWidget and TaskProgressWidget window style. +* [Fix] Minor fix in PgModelerCliApp to properly restore special objects when fixing models. + +v1.0.0-beta1 +------ +Release date: November 25, 2022
+ +* [New] Added the file themes/light/extra-ui-style.conf that holds extra style for the light theme. +* [New] Added dllexport symbol __lib* to functions and static attributes declarations in all namespaces. +* [New] Created defines for each library name __lib[NAME] in file [NAME]global.h which wraps Q_DECL_EXPORT/Q_DECL_IMPORT to export or import symbols of the libraries (needed for Windows). +* [New] Added the ability to toggle the magnifier tool in the main window. +* [New] Added a text search widget in the diff code preview on ModelDatabaseDiffForm. +* [New] Added unary operators for enum operations: |= , &= , ^= +* [New] Added a new implementation of CSV file loading based on RFC4180. Now the classes CsvParse and CsvDocument are responsible for parsing CSV files. +* [Change] Disabled unneeded conditional code in MainWindow. +* [Change] Adjusted the font weight in toolbar actions. +* [Change] Minor text adjustment in DonateWidget. +* [Change] Minor adjustments in UI stylesheets. +* [Change] Refactored TemplateType and all its derived classes to avoid the error "explicit specialization of 'type_names'" when building with clang. +* [Change] Adjusted the zoom in/out actions enabled state according to the current model's zoom factor. +* [Change] Adjusted AppearanceConfigWidget to load the extra-ui-style.conf. +* [Change] Adjusted the behavior of the magnifier action in MainWindow. +* [Change] Minor adjustment in MainWindow::setBottomFloatingWidgetPos to take into account the main menu bar height when visible. +* [Change] Changed the MetadataHandlingForm's Apply and Cancel actions to Execute and Close. +* [Change] Minor refactor in ModelFixForm to remove clangd warning. +* [Change] Adjusted the icon of the current input model/DB in the partial diff tab in ModelDatabaseDiffForm. +* [Change] Adjusting the context object in thread signal/slot connections in ModelExportForm. +* [Change] Adjusted plugins and arranged object actions in the main menu. +* [Change] Adjusted the captured variables in lambda slots avoiding default capturing [&]. +* [Change] Added a context object parameter in connect() which receives lambda slots. +* [Change] Refactored MainWindow signal/slot connections to the new syntax. +* [Change] Refactored ModelWidget signal/slot connections to the new syntax. +* [Change] Refactored ModelDatabaseDiffForm signal/slot connections to the new syntax. +* [Change] Refactored ModelExportForm signal/slot connections to the new syntax. +* [Change] Refactored ModelObjectsWidget signal/slot connections to the new syntax. +* [Change] Refactored ModelValidationWidget signal/slot connections to the new syntax. +* [Change] Refactored SQLExecutionWidget signal/slot connections to the new syntax. +* [Change] Refactored TableDataWidget signal/slot connections to the new syntax. +* [Change] Refactored SourceCodeWidget signal/slot connections to the new syntax. +* [Change] Refactored UpdateNotifierWidget signal/slot connections to the new syntax. +* [Change] Refactored OperationListWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectsTableWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectsFilterWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectSelectorWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectRenameWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectFinderWidget signal/slot connections to the new syntax. +* [Change] Refactored ObjectDepsRefsWidget signal/slot connections to the new syntax. +* [Change] Refactored NumberedTextEditor signal/slot connections to the new syntax. +* [Change] Refactored NewObjectOverlayWidget signal/slot connections to the new syntax. +* [Change] Refactored ModelOverviewWidget signal/slot connections to the new syntax. +* [Change] Refactored ModelNavigationWidget signal/slot connections to the new syntax. +* [Change] Refactored LineNumbersWidget signal/slot connections to the new syntax. +* [Change] Refactored LayersWidget signal/slot connections to the new syntax. +* [Change] Refactored LayersConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored FindReplaceWidget signal/slot connections to the new syntax. +* [Change] Refactored FileSelectorWidget signal/slot connections to the new syntax. +* [Change] Refactored CustomSQLWidget signal/slot connections to the new syntax. +* [Change] Refactored CsvLoadWidget signal/slot connections to the new syntax. +* [Change] Refactored ColorPickerWidget signal/slot connections to the new syntax. +* [Change] Refactored CodeCompletionWidget signal/slot connections to the new syntax. +* [Change] Refactored ChangelogWidget signal/slot connections to the new syntax. +* [Change] Refactored SQLToolWidget signal/slot connections to the new syntax. +* [Change] Disabled custom font size for hint boxes in BaseObjectWidget, ModelDatabaseDiffForm, ModelFixForm, and ModelWidget. +* [Change] Refactored SwapObjectsIdsWidget signal/slot connections to the new syntax. +* [Change] Refactored ModelValidationHelper signal/slot connections to the new syntax. +* [Change] Refactored ModelRestorationForm signal/slot connections to the new syntax. +* [Change] Refactored ModelFixForm signal/slot connections to the new syntax. +* [Change] Refactored ModelExportHelper signal/slot connections to the new syntax. +* [Change] Refactored MetadataHandlingForm signal/slot connections to the new syntax. +* [Change] Refactored DataManipulationForm signal/slot connections to the new syntax. +* [Change] Refactored DatabaseImportForm signal/slot connections to the new syntax. +* [Change] Refactored DatabaseExplorerWidget signal/slot connections to the new syntax. +* [Change] Refactored BugReportForm signal/slot connections to the new syntax. +* [Change] Refactored SnippetsConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored RelationshipConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored BaseForm::setMainWidget to use the new signal/slot connections to syntax +* [Change] Refactored PluginsConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored GeneralConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored ConnectionConfigWidget signal/slot connections to the new syntax. +* [Change] Refactored Messagebox signal/slot connections to the new syntax. +* [Change] Refactored ViewWidget signal/slot connections to the new syntax. +* [Change] Refactored TypeWidget signal/slot connections to the new syntax. +* [Change] Refactored TriggerWidget signal/slot connections to the new syntax. +* [Change] Refactored TextboxWidget signal/slot connections to the new syntax. +* [Change] Refactored TableWidget signal/slot connections to the new syntax. +* [Change] Refactored SequenceWidget signal/slot connections to the new syntax. +* [Change] Refactored RuleWidget signal/slot connections to the new syntax. +* [Change] Refactored RoleWidget signal/slot connections to the new syntax. +* [Change] Refactored RelationshipWidget signal/slot connections to the new syntax. +* [Change] Refactored ReferenceWidget signal/slot connections to the new syntax. +* [Change] Refactored ProcedureWidget signal/slot connections to the new syntax. +* [Change] Refactored PolicyWidget signal/slot connections to the new syntax. +* [Change] Refactored PgSqlTypeWidget signal/slot connections to the new syntax. +* [Change] Refactored PermissionWidget signal/slot connections to the new syntax. +* [Change] Refactored ParameterWidget signal/slot connections to the new syntax. +* [Change] Refactored OperatorClassWidget signal/slot connections to the new syntax. +* [Change] Minor refactor in CoreUtilsNs::isReservedKeyword. +* [Change] Removed Qt::WindowContextHelpButtonHint from default window flags in BaseForm constructor. +* [Change] Refactored IndexWidget signal/slot connections to the new syntax. +* [Change] Refactored GenericSqlWidget signal/slot connections to the new syntax. +* [Change] Refactored FunctionWidget signal/slot connections to the new syntax. +* [Change] Refactored EventTriggerWidget signal/slot connections to the new syntax. +* [Change] Refactored ElementWidget signal/slot connections to the new syntax. +* [Change] Refactored ElementsTableWidget signal/slot connections to the new syntax. +* [Change] Refactored DomainWidget signal/slot connections to the new syntax. +* [Change] Refactored ConstraintWidget signal/slot connections to the new syntax. +* [Change] Refactored ColumnWidget signal/slot connections to the new syntax. +* [Change] Refactored ColumnPickerWidget signal/slot connections to the new syntax. +* [Change] Refactored CollationWidget signal/slot connections to the new syntax. +* [Change] Refactored BaseObjectWidget signal/slot connections to the new syntax. +* [Change] Refactored BaseFunctionWidget signal/slot connections to the new syntax. +* [Change] Refactored AggregateWidget signal/slot connections to the new syntax. +* [Change] Refactored BaseForm signal/slot connections to the new syntax. +* [Change] Refactored SchemaView signal/slot connections to the new syntax. +* [Change] Refactored TableView signal/slot connections to the new syntax. +* [Change] Refactored TextboxView signal/slot connections to the new syntax. +* [Change] Refactored RelationshipView signal/slot connections to the new syntax. +* [Change] Refactored ObjectsScene signal/slot connections to the new syntax. +* [Change] Refactored GraphicalView signal/slot connections to the new syntax. +* [Change] Refactored BaseObjectView signal/slot connections to the new syntax. +* [Change] Refactored SourceEditorWidget signal/slot connections to the new syntax. +* [Change] Refactored SchemaEditorForm signal/slot connections to the new syntax. +* [Change] Refactored PgModelerCliApp signal/slot connections to the new syntax. +* [Change] Refactored CrashHandlerForm signal/slot connections to the new syntax. +* [Change] Removed the files basetype.h and basetype.cpp. +* [Change] Moved all the code from BaseType to TemplateType. +* [Change] Renamed getCodeDefinition, getAlterDefinition, and getDropDefintion to respectively getSourceCode, getAlterCode, and getDropCode. +* [Change] Moved the element type ids in XmlParser to XmlParser::ElementType. +* [Change] Removed unused constants in SourceCodeWidget. +* [Change] Moved config widget ids constants in ConfigurationForm to ConfigurationForm::ConfWidgetsId. +* [Change] Moved main window view ids to MainWindow::MWViewsId. +* [Change] Moved table buttons and item color constants in ObjectsTableWidget to ObjectsTableWidget::ButtonConf and ObjectsTableWidget::TableItemColor. +* [Change] Moved index attributes (buffering, concurrent, unique) constants to Index::IndexAttribs. +* [Change] Moved relationship break mode ids in ModelWidget to ModelWidget::RelBreakMode. +* [Change] Moved validation info type constants in ValidationInfo to ValidationInfo::ValType. +* [Change] Moved diff type constants in ObjectsDiffInfo to ObjectsDiffInfo::DiffType. +* [Change] Moved diff options constants in ModelsDiffHelper to ModelsDiffHelper::DiffOptions. +* [Change] Moved thread ids constants in ModelDatabaseDiffForm to ModelDatabaseDiffForm::ThreadId. +* [Change] Moved row operation ids constants in DataManipulationForm to DataManipulationForm::OperationId. +* [Change] Moved object attribute ids in DatabaseImportForm to DatabaseImportForm::ObjectAttrId +* [Change] Moved icon types and button ids constants in Messagebox to, respectively, Messagebox::IconType and Messagebox::ButtonsId. +* [Change] Moved tab id constants in RelationshipWidget to RelationshipWidget::TabId. +* [Change] Moved pending operations ids in MainWindow to MainWindow::PendingOpId. +* [Change] Minor adjustment in cached name/signature checking in DatabaseImportHelper::getObjectName. +* [Change] Minor improvement in DatabaseImportHelper::getObjectName to cache names and signatures to avoid repeatedly configuring names on each call. +* [Change] Moved the type function ids constants in Type to Type::FunctionId. +* [Change] Moved the type config constants in Type to Type::TypeConfig. +* [Change] Moved font factor constants in namespace GuiUtils to GuiUtilsNs::FontFactorId. +* [Change] Moved transition table ids in Trigger to Trigger::TransitionTableId. +* [Change] Moved transform functions constants in Transform to Transform::FunctionId. +* [Change] Moved text attributes constants in Textbox to Textbox::TextAttribs. +* [Change] Minor change in ModelWidget::saveModel to create a backup file in the same places as the original model file. +* [Change] Refactored BaseObjectView to use ColorId enum. +* [Change] Moved the Tag::ColorId to the global scope in basegraphicobject.h since the enum usage is not exclusive to tags. +* [Change] Fixed the underlying type of some enums. +* [Change] Moved role type and options constants from Role to, respectively, Role::RoleType and Role::RoleOpts. +* [Change] Moved name pattern constants in Relationship to Relationship::PatternId. +* [Change] Moved SQL type constants in Reference to Reference::SqlType. +* [Change] Moved the reference type constants in Reference to Reference::ReferType. +* [Change] Moved privileges ids constants in Permission to Permission::PrivilegeId. +* [Change] Moved operator class element type constants in OperatorClassElement to OperatorClassElement::ElementType. +* [Change] Moved constants related to argument ids and operators ids in Operator to, respectively, Operator::ArgumentId and Operator::OperatorId. +* [Change] Minor change in databaseimportform.ui, moved the tool buttons that control items selection/collapsing to the top of the section. +* [Change] Moved function ids constants in Operator to Operator::FunctionId. +* [Change] Moved chain type constants in Operation to Operation::ChainType. +* [Change] Moved operation types in Operation to Operation::OperType. +* [Change] Moved function constants in Language to Language::FunctionId. +* [Change] Moved version constants in Extension to Extension::VersionId. +* [Change] Moved the sorting constants of Element to Element::SortOrder. +* [Change] Moved DatabaseModel change log constants to DatabaseModel::LogFields. +* [Change] Moved DatabaseModel metadata attributes constants to DatabaseModel::MetaAttrOptions. +* [Change] Moved the code generation mode constants of DatabaseModel to DatabaseModel::CodeGenMode. +* [Change] Moved CopyOptions constants to CopyOptions::CopyOpts and CopyOptions::CopyMode. +* [Change] Moved SpatialType variation constants to enum SpatialType::VariationId. +* [Change] Moved UserTypeConfig type config constants to enum UserTypeConfig::TypeConf. +* [Change] Moved Constraint columns constants to enum Constraint::ColumnsId. +* [Change] Moved Constraint actions events constants to enum Constraint::ActionEvent. +* [Change] Moved Conversion constants to enum Conversion::EncondingId. +* [Change] Moved constants Collation::Lc* to Collation::LocaleId. +* [Change] Moved Cast::*Type to enum Cast::DataTypeId. +* [Change] Move cast type constants to enum Cast::CastType. +* [Change] Moved BaseTable::*Section constants to BaseTable::TableSection. +* [Change] Constants related to relationship type and label ids were moved, respectively, to enums BaseRelationship::RelationshipType and BaseRelationship::RelationshipLabel +* [Change] Moved the Aggregate::*Func constants to Aggregate::FunctionId enum. +* [Change] Moved all ResultSet::*Tuple constants to the enum ResultSet::TupleId. +* [Change] Moved the Catalog query filter constants to Catalog::QueryFilter enum. +* [Change] Created bitwise operators for enums in enumtype.h. +* [Change] Moved the constants ObjDescriptor, NameLabel, TypeLabel, and ConstrAliasLabel of TableObjectView to TableObjectView::ChildObjectId. +* [Change] Moved the constants Connection::Op* to the enum Connection::ConnOperation. +* [Change] Moved RoundRectItem corner constants to RoundedRectItem::RectCorners. +* [Change] Moved the global enum CollapseMode to BaseTable::CollapseMode. +* [Change] The static attributes ObjectsScene::Layer*Color were moved to LayerAttributes scoped enum. +* [Change] Renamed the enum_cast() to enum_t and moved to enumtype.h. +* [Change] Moved the constexpr attributes that reference toggler buttons to enum AttributesTogglerItem::TogglerButton. +* [Change] Reunited all row editing actions in DataManipulationForm in a single menu under "Edit" action. +* [Change] In SQLToolWidget when requesting the source code display of an object in the objects' tree, the source code pane will be popped up if not being shown. +* [Change] Minor improvement in CsvParser::parserBuffer to replace Windows/MacOs line breaks (\r\n and \r) by Unix only line break (\n). +* [Change] Refactored PhysicalTable::getInitialDataCommands to use CsvParser/CsvDocument. +* [Change] Minor adjustment in CsvParser to raise an exception on the malformed document due to missing close text delimiter. +* [Change] Fixes the loading of complex CSV files in TableDataWidget. +* [Change] Changed the way pgModeler imports CSV files to be used as initial table data. +* [Fix] Minor fix in MainWindow when building with DEMO_VERSION flag. +* [Fix] Fixed a bug in AppearanceConfigWidget that was randomly changing the UI theme when the user tweaks the UI style form. +* [Fix] Additional fix for false-positive diffs when functions were using an array of user-defined types. +* [Fix] Fixed a crash happening in the moment a renamed object got its source reloaded in DatabaseExplorerWidget. +* [Fix] Fixed a bug in CopyOptions that was not initializing attributes in the default constructor. +* [Fix] Minor fix in BugReportForm message box text. +* [Fix] Fixed the tool button style of plugins action in model_actions_tb in MainWindow. +* [Fix] Minor fix in FileSelectorWidget and ObjectSelectorWidget to capture mouse press instead of focus to display the respective selection dialogs. +* [Fix] Fixed a bug in StyledTextboxView that was not emitting s_objectDimensionChanged when (re)configuring it. +* [Fix] Fixed UpdateNotifierWidget style for the dark theme. +* [Fix] Fixed a bug in Catalog::getCatalogQuery that was not placing the custom filter in the right place in the query. +* [Fix] Fixed a bug that was resetting the fade-out state of objects. +* [Fix] Fixed a bug in database import that was failing to import operators in certain cases. +* [Fix] Fixed a bug when importing functions that contain parameters composed of arrays of user-defined types. +* [Fix] Fixed a bug in AppearanceConfigWidget that was not persisting changes in minimum opacity and attributes numbers per page spin boxes. +* [Fix] Minor fix in DatabaseModel::getObject(QString,ObjectType) to search for an object by its signature and name. + +v1.0.0-beta +------ +Release date: September 10, 2022
+ +* [New] Added data dictionary entry for indexes, triggers, and sequences. +* [New] Columns, indexes, triggers, and constraints now have their own method to generate their data dictionaries. +* [New] Created the objects.sch to be reused when generating data dictionaries for columns, constraints, indexes, triggers, and sequences. +* [New] Added split SQL code generation modes to export form. +* [New] Added the ability to export dependencies or children SQL in split mode at CLI. +* [New] Added code generation options to DatabaseModel::saveSplitSQLDefinition. +* [New] Added a fix step in CLI to remove encrypted attribute from tag. +* [New] Added an info message in the FindReplaceWidget reporting the search status (not found, cycle search, replacements made, etc). +* [New] Added a text search widget in SourceCodeWidget. +* [Change] Tab order adjustments in several forms and widget. +* [Change] Adjusted the stylesheet of the data dictionary. +* [Change] pgModeler CLI menu and messages fixed/improved. +* [Change] Improved the interaction between the magnifier tool and the canvas area. Now the user can select multiple objects, move, and control the zoom with the magnifier tool activated. +* [Change] Adjusted the size of the magnifier frame according to the primary screen size. +* [Change] Improved the XMlParser exceptions raised to point the file that generated the error. +* [Change] Dropped the support for PostgreSQL 9.x. +* [Change] Dropped the attribute "Encrypted" from the role form. +* [Change] Connection class now aborts the connection to PostgreSQL 9.x servers. +* [Change] Changed the shortcut key of the magnifier tool from Ctrl + Alt to F9. +* [Change] Changed the "edit item" icon on ObjectsTableWidget. +* [Change] Changed the default size of splash screen on screens with device pixel ratio = 1. +* [Fix] Fix a crash in macOS when right-clicking a blank portion of the canvas when there are objects selected. +* [Fix] Minor fix the warning icon size and position in FileSelectorWidget. +* [Fix] Fixed a bug in BaseObject::isValidName that was not considered valid a name in the format schema."object". +* [Fix] Fixed the diff generation for materialized views. +* [Fix] Fixed a bug in CLI that was not correctly fixing domains in models created in 0.8.2. +* [Fix] Fixed the appearance of the about widget in pgmodeler-se. +* [Fix] Fixed the CLI in such a way to use QRegularExpression correctly on large text buffers. +* [Fix] Minor fix in standalone connection dialog to alert the user about unsaved connection configuration. +* [Fix] Minor fix in ConnectionsConfigWidget to avoid adding connections with duplicated aliases. + +v1.0.0-alpha1 +------ +Release date: June 21, 2022
+ +* [New] Added PostgreSQL 15 as the default version for code generation. +* [New] Added a workaround in MainWindow constructor to force the application of UI themes on Windows and Mac. +* [New] Added the methods GlobalAttributes::getConfigParamFromFile and GlobalAttributes::setCustomUiScaleFactor. +* [New] Add support for custom UI scaling and UI icons size selection in AppearanceConfigWidget. +* [New] Created the method Relationship::updateGeneratedObjects. +* [New] pgModeler now saves and restores the QFileDialog instances geometry/state in the file filedlg.conf. +* [New] Created the method QApplication::loadTranslation to reuse translation loading routines. +* [Change] Minor adjustment in assets/schemas/catalog/database.sch in order to retrieve the last system oid from pg_depend. +* [Change] Removed the class CustomMenuStyle since its use is not needed anymore. +* [Change] Refactored MainWindow constructor by creating small methods for specific initialization tasks. +* [Change] Changed the references to STL classes/algorithms by using the namespace std::. +* [Change] Removed global "using namespace std" to avoid breaking the building on mingw64. +* [Change] Replaced QtCompat classes with Qt 6 specific code. +* [Change] Adjusted the layout spacing in all *.ui files. +* [Change] Updated several icon sizes due to Qt 6 improved auto-scale factor. +* [Change] Replaced deprecated attribute QPalette::Foreground in TableDataWidget. +* [Change] Minor improvement in DatabaseExplorerWidget::dropObject to show the complete location of the object being dropped (schema, table, DB). +* [Change] In DatabaseImportHelper::createSchema if the schema to be created is public or pg_catalog, pgModeler will just ignore them because these schemas already exist in the model being imported. +* [Change] When printing a model with page numbers enabled pgModeler now will add the column and row info of the current page being printed. +* [Change] Moved from deprecated QPrinter API to newer one in Qt 6. +* [Change] Adjusted the behavior of ObjectFinderWidget, now "Exact match" option is only enabled when using regular expressions. +* [Change] Adjusted the generation of CDATA elements in XML schema files. +* [Change] Adjusted the syntax highlighting conf files. +* [Change] Adjusted the XML highlighting conf files. +* [Change] Removed the support to partial-match attribute in syntax highlight conf files. +* [Change] Removed partial matching from SyntaxHighlighter. +* [Change] SyntaxHighlighter will raise an error if an invalid regex pattern is detected during file loading. +* [Change] Replaced all QRegExp usages by QRegularExpression due to the deprecation of the former class in Qt 6. +* [Change] Forcing C++17 building and the deprecation of any API before Qt 6. +* [Change] Minor improvement in Relationship::addColumnsRelGenPart to allow the creation of missing columns only as part of the routines in Relationship::updateGeneratedObjects. +* [Change] Minor change in DatabaseModel::validateRelationships to update tables and schemas geometry only at the end of the method. +* [Change] Disabling the extra relationship validation in DatabaseModel::loadModel. +* [Change] Improved the procedure that tries to recreate invalid relationships in DatabaseModel::validateRelationships. +* [Change] Refactored the way relationships are validated in DatabaseModel improving the overall operation speed. +* [Change] Changing the catalog query filter in PgModelerCliApp::importDatabase and ModelDatabaseDiffForm::importDatabase to avoid retrieving and creating system objects unnecessarily. +* [Change] Minor adjustments in pen width factor in RelationshipView::getDefaultPenWidth. +* [Change] Minor change in identifier relationship rendering. +* [Change] Removed the unneeded use of QString("") instantiation in several parts. +* [Change] The delete operation on ModelWidget now displays a wait cursor while running. +* [Fix] Fixed a bug in ConnectionsConfigWidget::openConnectionsConfiguration that was preventing reloading the original conf file when the user clicked cancel. +* [Fix] Fixed a bug in AppearanceConfigWidget that was applying the font style correctly to the source code preview. +* [Fix] Fix splitters handler sizes. +* [Fix] Fixed the QMenu configuration in several parts to use the new API of Qt 6. +* [Fix] Minor fix in LineNumbersWidget to render numbers in the correct height. +* [Fix] Fixed the resizing and positioning of the code completion widget in the first show. +* [Fix] Fixed a signal/slot connection in GeneralConfigWidget. +* [Fix] Fix a crash in ObjectsScene::mousePressEvent when building with Qt 6. +* [Fix] Fixed a typo in the error message in Tablespace::setDirectory. +* [Fix] Minor fix in Catalog::parseRuleCommands. +* [Fix] Minor fix in ModelObjectsWidget::updateObjectsList. Instead of using an empty pattern, we needed to force the wildcard * so the search returns all objects. +* [Fix] Fixed a bug in the column propagation mechanism that was failing to (re)create columns properly when the model was using lots of identifier relationships. +* [Fix] Minor fix in ElementsTableWidget to display "Default" in Sorting and Nulls columns instead of a blank text when no sorting method is defined for an element. +* [Fix] Fixed a bug in PhysicalTable::setColumnsAttribute that was ignoring exclude constraints when determining the use of the last comma in the table's SQL code. +* [Fix] Import process now correctly configures sorting options for excluding constraints and indexes. +* [Fix] Minor fix in RelationshipView to use the method getDefaultPenWidth when configuring lines and descriptors. +* [Fix] Fixed the scattered objects arrangement mode to make tables less sparse over the canvas. +* [Fix] Fixed a crash when trying to swap relationships in SwapObjectsIdsWidget. +* [Fix] Fixed blurry icons on TaskProgressWidget. + +v1.0.0-alpha +------ +Release date: April 11, 2022
+ +* [New] pgModeler 1.0 will now copy compatible config files from 0.9.x if the older configuration dir is found on the first execution. +* [New] Added extra constants to ObjectsTableWidget to control the coloring of items in DataManipulationForm according to the theme in use. +* [New] Added an extra tab in Messagebox stack trace info called "Extra info" that displays only error's extra info to quickly help to identify any problem. +* [New] AppearanceConfigWidget now switches between light/dark themes on-the-fly. +* [New] Added custom appearance config files in conf/themes for each theme color. +* [New] Added support for customizing objects' shadow color. +* [New] Textboxes are now rounded at corners. +* [New] Created the files ui-medium.conf and ui-small.conf that controls the ui style in medium (2k) and small (1080p and below) screen sizes. +* [New] Added the class CustomMenuStyle that configures a custom size for QMenu icons. +* [New] Added an implementation for SimpleColumn::operator = to avoid compiler warnings. +* [New] Added an icon for update found notification in MainWindow. +* [New] Adding cool new icons and project logo. +* [New] CLI now restores the changelog during the fix operation. +* [New] Added the instruction $$QMAKE_LIBS_EXECINFO to apps/pgmodeler/pgmodeler.pro +* [Change] Minor adjustment in pgmodeler.pri to accept custom XML_??? and PGSQL_??? vars on Linux +* [Change] Removed the code generation of rules/indexes/triggers in the "Code preview" tab at ViewWidget since these objects' codes aren't appended to the parent view's code. +* [Change] Removed the icon of the QToolBar's extended button via CSS. +* [Change] ColorPickerWidget color button is now resized according to the tool button icon size. +* [Change] ObjectSelectorWidget was simplified to keep UI more uniform. Now it uses a QLineEdit instead of a QPlainTextEdit. +* [Change] Removed all files suffixed as _grp.png from resources and code. +* [Change] The routine that applies the UI stylesheet was moved from PgModelerApp to AppearanceConfigWidget. +* [Change] Improved the Messagebox resizing during the first show. +* [Change] Disabling Qt 5.15.x and below due to the starting of the transition to Qt 6.x +* [Change] Minor layout adjustment in pgmdoeler-se/SchemaEditorForm. +* [Change] Gridlines and delimiters lines now follow the objects' border width. +* [Change] Adjusted the colors of database objects in the dark theme. +* [Change] Minor adjustment in cursor icon when adding new graphical objects to the model. +* [Change] Messagebox will hide "Extra info" tab when the exception does not carry extra error info. +* [Change] ObjectsScene's relationship addition line now follows the page delimiter colors. +* [Change] Updated icns files in apps/pgmodeler/res. +* [Change] The configuration files directory in macOS is now named pgmodeler-1.0 to follow the same pattern as in other OSes. +* [Change] Removed the use of attributes Qt::AA_UseHighDpiPixmaps and Qt::AA_EnableHighDpiScaling. +* [Change] Floating widgets like LayersConfigWidget, AboutWidget, ChangelogWidget, and DonateWidget had CSS changed to obey QPalette changes when using themes. +* [Change] pgModeler default UI theme is now the dark one. +* [Change] Moved the constants ProtRowBgColor, ProtRowFgColor, RelAddedRowBgColor, RelAddedRowFgColor from GuiUtilsNs to ObjectsTableWidget. +* [Change] Update the signal/slot connections in AppearanceConfigWidget to the new syntax connect(obj, &Class::signal, obj1, &Class1::slot) (Experimental) +* [Change] Updated the relationship sample images in RelationshipConfigWidget. +* [Change] Updated the icons of the operations' modes in ModelExportForm. +* [Change] Minor component size adjust in GeneralConfigWidget. +* [Change] Removed unused stylesheet images. +* [Change] The configuration files renamed. Changes pgmodeler.conf -> general.conf, objects-style.conf -> appearance.conf. +* [Change] AppearanceConfigWidget now can handle settings in the file appearance.conf. +* [Change] Minor improvement in BaseConfigWidget::loadConfiguration. +* [Change] DataManipulationForm now deactivates tool buttons' texts according to the dialog height compared to the screen's height. +* [Change] Moved the appearance settings from GeneralWidget to AppearanceWidget. +* [Change] Minor adjustments in sample models. +* [Change] Improved the logic used to load extra stylesheet files in PgModelerApp. +* [Change] Changed the default source code font to 12pt. +* [Change] Adjusted the sizes of descriptors in RelationshipView, BaseTableView, and AttributesTogglerItem to reflect the new default font size. +* [Change] Changed default font size in canvas to 11pt. +* [Change] pgModeler 1.0 configuration directory was renamed from "pgmodeler" to "pgmodeler-1.0" since some config files are now incompatible with 0.9.x. +* [Change] Updated the Windows icons for the apps. +* [Change] Minor size adjustments in pgmodeler-se subproject. +* [Change] Changed the configuration dir name to pgmodeler-1.0 to avoid conflicts with 0.9.x confs. +* [Change] UI stylesheets are now selected depending on the screen size. +* [Change] Changed default icon size of combo boxes. +* [Change] Several layout margins/spacing adjustments in UI files. +* [Change] Size adjustments in ui/settings/*.ui +* [Change] Size adjustments in ui/tools/bugreportform.ui,databaseexplorerwidget.ui,metadatahandlingform.ui,modeldatabasediffform.ui +* [Change] Adjusted the size of icons in tool buttons. +* [Change] Standardization of layout spacing/margin in widgets. +* [Change] Tool buttons resize and layout spacing adjustments. +* [Change] Minor ui component resizes in several forms/widgets. +* [Change] Adjusted sizes in mainwindow.ui welcomewidget.ui. +* [Change] Adjusted ui components on sqlexecutionwidget.ui, modelobjectswidget.ui, operationlistwidget.ui. +* [Change] Adjusted the splash screen asset. +* [Change] Minor icons size adjustment in mainwindow.ui, sceneinfowidget.ui, welcomewidget.ui, modelnavigationwidget.ui. +* [Change] Minor update on toolbars title in MainWindow. +* [Change] Removed *_big* icons. +* [Change] Renamed general_tb to tools_acts_tb and controls_tb to model_acts_tb. +* [Change] Adjustment in the toolbars icon sizes in MainWindow. +* [Change] Adjustment in the stylesheets for the new UI style. +* [Change] Improved the mechanism that guesses if an FK relationship can be rendered as 1:1 or 1:N. +* [Change] Minor adjust in CLI so the "hide-ext-attribs" property in models created before 0.9.2 can be correctly replaced by "collapse-mode" during the model fix operation. +* [Change] PostgreSQL 14 is now the default version for code generation. +* [Change] Disabling the usage of the flag QGraphicsItem::ItemClipsChildrenToShape in BaseTableView to avoid wrong clipping of column items during export to PNG. +* [Change] The workaround in CLI that forces the loading of the offscreen plugin will now be triggered only in the absence of $DISPLAY env var. +* [Change] Isolated the variables common to executables subproject in the file apps/apps.pri. +* [Fix] Fixed the detection of ENTER/RETURN press to find objects in ObjectFinderWidget. +* [Fix] Fixed a bug in ModelWidget that was causing the scene to not recover from blocked signal status if an exception was thrown in ModelWidget::protectObject. +* [Fix] Minor fix in different places that QScreen instances are used. Instead of getting the screen where the active window is, we get the primary screen of the application. +* [Fix] Minor fix in CodeCompletionWidget to resize correclty according to the contents. +* [Fix] Fixed a critical bug that was preventing the importing of data types in CamelCase form. +* [Fix] Minor fix in SyntaxHighlighter to set the correct height of the parent QPlainTextEdit when using single-line mode. +* [Fix] Fixed the configuration of the shadow object in RelationshipView. +* [Fix] Fixed a bug in RelationshipWidget that was not allowing the duplication of attributes and constraints. +* [Fix] Fixed a bug in AttributesTogglerItem that was not resizing buttons when the user changed the font factor. +* [Fix] Fixed an exception in ObjectFinderWidget when searching using attributes different from the name, comment, and schema. +* [Fix] Fixed the long name of foreign-data wrappers. +* [Fix] Fixed a bug when comparing serial and integer columns on diff that was not reusing sequences or changing types properly. +* [Fix] Fixed the SVG exporting process avoiding truncating the resulting graphics. + +v0.9.4 +------ +Release date: December 17, 2021
+ +* [New] Added a fix step in CLI to reconstruct enum types XML code in new format. +* [Change] Changed the way XML code for enum types is generated and loaded. +* [Change] Minor improvement in reverse engineering to import enum types in the new format. +* [Change] Minor adjust in the demo version warning message. +* [Change] Minor adjustment in permission id generation. Now the object's signature is used instead of name. +* [Change] Minor refactor in the reconstruction of XML related to enum types in CLI. +* [Fix] Minor fix in deployment script to support new libicui versions. +* [Fix] Minor fix in order to set read/write permissions when copying configuration files with read-only permissions. +* [Fix] Minor fix in CLI to avoid the usage of '-platform offscreen' when calling the application. +* [Fix] Fixed a bug in file selectors on ModelExportForm that was not allowing to select output folders on Windows and macOs. + +v0.9.4-beta1 +------ +Release date: November 08, 2021
+ +* [New] Added extra PostGiS data types to PgSQLType. +* [New] Created the method PgSqlType::isPostGiSType() which returns true if the current type is a PostGiS one. +* [New] Created the method PgSqlType::reset() that clears some attributes of the type. +* [New] Added the built-in type pg_lsn in order to make databases using timescaledb extension to be imported correctly. +* [Change] Minor adjustment in windowsdeploy.sh to create zip packages. +* [Change] Minor adjustment in demo version warning messages. +* [Change] Adjusted the catalog query filters in ModelDatabaseDiffForm to retrieve system and extension objects according to the checkboxes "Import system objects" and "Import extension objects". +* [Change] Adjusted the reverse engineering in such a way that the table children will follow the SQL disabled state of their parent tables. +* [Change] Allowing importing pg_lsn attributes in usertype.sch. +* [Change] Allowing the use of commas in enum type labels. +* [Change] Improved the output of model fix operation in CLI. +* [Change] The constants DataSeparator, UnescValueStart, UnescValueEnd, WildcardChar, FilterSeparator, FilterWildcard, FilterRegExp were moved from CoreUtilsNs to UtilsNs in order to be used in the parsers module. +* [Change] In SchemaParser the meta char $ds (dollar sign) was renamed to $ms (money sign). Also, a new meta char $ds (data separator) was added and translates to the special data separator character UtilsNs::DataSeparator. +* [Change] Minor adjustments in table.sch and foreigntable.sch schema files. +* [Change] Improved DatabaseModel::getUserDefTypesReferences in order to get all references to postgis data types. +* [Change] Improved ModelValidationHelper in order to set postgis extension a default comment when automatically creating it. +* [Change] PgSQLTypeWidget now can be configured in such a way to disallow the configuration of type qualifiers like length, precision, interval, and some other. This is useful when configuring data types for objects that don't require such attributes in the data type like parameter, aggregates, transforms, casts, operators. +* [Change] Changed the behavior of Parameter::getCodeDefinition when generating SQL code. Now, any type qualifier (except dimension descriptor []) will be discarded. +* [Fix] Fixed the catalog query that lists policies. +* [Fix] Added a minor workaround in DatabaseImportHelper::getType in order to treat the "any" pseudo-type correctly. +* [Fix] Minor fix in DatabaseImportForm in order to disable option buttons when no connection is selected. +* [Fix] Fixed a segfault when importing domains with long expressions. +* [Fix] Fixed the broken SQL generation for tables with columns/constraints disabled. +* [Fix] Fix the name of the checkbox related to updates checking to avoid breaking the building when enabling NO_UPDATE_CHECK via qmake. +* [Fix] Fixed the shortcuts of Copy/Paste actions in DataManipulationForm. + +v0.9.4-beta +------ +Release date: September 20, 2021
+ +* [New] Added the shortcut Alt+C to trigger the cancel action in DatabaseImportForm ModelDatabaseDiffForm and ModelExportForm. +* [New] Added support for the generation of GRANT/REVOKE commands to control roles memberships via the diff process. +* [New] Added a fix step to reconfigure roles membership considering the deprecation of Role:RefRole attribute. +* [New] Added support for included columns on indexes. +* [New] Added the ability to reference view columns on indexes. +* [New] Added support to use view's SimpleColumn in ColumnPickerWidget as well as Index. +* [New] Added .dtd extension to SchemaEditorForm::showFileDialog. +* [New] Created the widget ColumnPickerWidget by isolating the code that handles constraint columns in ConstraintWidget for reusing in other portions of the tool. +* [New] Added the method Constraint::addColumns(). +* [New] Two buttons were added aside the date input fields in partial diff tab (ModelDatabaseDiffForm) in order to allow the quick assignment of the first and last modification dates. +* [New] Added support for toggling update notifications for alpha/beta versions. +* [New] Added support for save and restore the tree state in DatabaseExplorerWidget. +* [Change] Minor improvement in ModelsExportHelper by adding more breaking points related to export canceled. +* [Change] Minor improvement in ObjectRenameWidget in such a way to fill the new name field with the object's name in the first show when a single object is selected for renaming. +* [Change] Dropped the support for MemberOf (Role::RefRoles) in order to make the diff between two roles more precise. +* [Change] In RoleWidget the tab "Member Of" now works only as a convenience feature that adds the role being edited to the ones listed in that tab. +* [Change] Restored the file pgmodeler.appdata.xml. +* [Change] Refactored BaseObject::isCodeDiffersFrom (and its variants in children classes) to use QStringList instead of vector as parameters. +* [Change] Allowing swap cluster level object ids in SwapObjectsIdsWidget when the objects are of the same kind. +* [Change] Minor refactoring in RoleWidget, Role and DatabaseModel to use Role::RefRole, Role::MemberRole and Rele::AdminRole constants as loop indexes. +* [Change] Minor adjustment in demo features. +* [Change] Minor refactoring in Role::setRoleAttribute. +* [Change] Minor improvement in ModelExportHelper::exportToDbms to send the SQL command via a signal when creating roles and the database. +* [Change] Improvements in pgmodeler-se in such a way to control syntax highlighting settings per open editor. +* [Change] Avoided the use of a working dir in .desktop file when installing mime types system-wide. +* [Change] Improved the way layers rectangles are updated after undoing/redoing operations in OperationListWidget. +* [Change] Isolated SimpleColumn struct on its own file for reusing in other modules. +* [Change] Moved the constants ProtRowBgColor, ProtRowFgColor, RelAddedRowBgColor, RelAddedRowFgColor from BaseObjectWidget to GuiUtilsNs. +* [Change] Changed the default match type in foreign key constraint to MATCH SIMPLE. +* [Change] Minor adjustment in the ModelWidget::updateSceneLayers to force the update of all schemas. +* [Change] Avoided a lambda function call when checking updates to prevent segfaults. +* [Change] Exceptions raised in BugReportForm when the "lastmodel" file isn't found are now ignored. +* [Change] Minor change in ModelValidationHelper to use table's signature instead of name during the name validation process. +* [Change] Avoided calling the functions xmlInitParser() and xmlCleanupParser() more than once per app execution in XmlParser class to avoid unexpected behavior. +* [Change] Minor adjustment in viewport drawing mode in order to redraw objects by bounding rect changes. +* [Change] Minor improvements in the changelog widget in order to display the first modification date. +* [Change] Refactored Connection::requestCancel in order to avoid using PQrequestCancel which is deprecated. +* [Fix] Fixed a glitch when drawing StyledTextboxView instaces. +* [Fix] Fix the diff between columns using PostGiS datatypes. +* [Fix] The attributes Qt::AA_UseHighDpiPixmaps and Qt::AA_EnableHighDpiScaling are now correctly set before the instantiation of Application based classes. +* [Fix] Fixed a crash in diff process caused by the ModelExportHelper instance when canceling the export to DBMS when an exception was raised. +* [Fix] Fixed a crash in SwapObjectsIdsWidget when the user tried to swap objects using arrow keys. +* [Fix] Fixed the tab names in RoleWidget. +* [Fix] Minor fix in DatabaseExplorerWidget to display view's children source code. +* [Fix] Fixed the building of IndexWidget on Qt 5.14 and below. +* [Fix] Fixed the problem on ModelDatabaseDiffForm that was not accepting pressing Return/Esc to respectively run the diff and close the dialog due to a conflict with the event loop instance in ModelDatabaseDiffForm::exec(). +* [Fix] Minor fix in the configuration of ObjectGroupId element in DatabaseImportForm::updateObjectsTree in order to avoid crashes when no root element is specified. +* [Fix] Fixed the generation of aggregate functions when they use functions that contain parameters in which data type have spaces (double precision, character varying). +* [Fix] Fixed a segfault that can happen when changing the number of parameters of a function already associated with an aggregate. +* [Fix] Additional fix for layers not being correctly loaded from dbm file. + +v0.9.4-alpha1 +------ +Release date: July 19, 2021
+ +* [New] The bulk editing form now can be confirmed by the Ctrl+Return shortcut. +* [New] The CLI now is capable of fixing models created before 0.9.4-alpha1 that have columns, functions, and other objects that reference extension types with simple names instead of schema-qualified names. +* [New] Added an option to GeneralConfigWidget to toggle the displaying of schema names of columns data types on design view. This option affects only the rendering of objects, the code generation will keep displaying user-defined type names in a schema-qualified way. +* [New] Created the DeletableItemDelegate which draws a delete button aside combobox items. +* [New] Added the ability to drop databases from the database listing in SQLToolWidget. +* [New] Added support to strikeout attribute in SyntaxHighlighter. +* [New] Created an auxiliary tool called pgModeler Schema Editor in order to help to edit *.sch files as well as validate their syntax. +* [New] GeneralConfigWidget now restores the sch-highlight.conf to default. +* [New] Added the environment variable name for schema editor app in GlobalAttributes. +* [New] Added a specific icon for CLI on Windows. +* [New] Added the methods SchemaParser::getCurrentColumn and SchemaParser::getCurrentLine. +* [New] Added signal s_hideRequested to FindReplaceWidget to notify connected slots that the close button on that widget was clicked. +* [New] Added an attribute capture-nearby to the word-separators tag that is read by SchemaParser to indicate if word separators must be capture altogether in the same word if they appear contiguously. +* [New] Added options to create only missing config files or recreate all config file in CLI. +* [New] Added support for saving SQL definition in split files. +* [New] Added support for split SQL generation in CLI. +* [New] Added the ability to cancel the SQL file export process in GUI. +* [New] Created the methods UtilsNs::saveFile and UtilsNs::loadFile in order to replace repetitive save/load code by them. +* [New] Created the function PgSqlVersions::parseString that checks the forced PostgreSQL version is valid, returning a fallback version when needed or raising an error if the version is malformed or is unsupported. +* [New] Added new metacharacter to SchemaParser: $hs for #, $ps for %, $at for @, $ds for $. +* [New] Added the option --force to the mime type handling operation on CLI. +* [Change] Changed the behavior of column click on DataManipulationForm. Now, the sorting is triggered by holding control and clicking the desired column. Clicking a column without holding control will select all the items in that column. +* [Change] Changed the behavior of extension types registration, now they will be forcibly registered with complete name (schema.name) in order to follow the same rule of user-defined data types so the reverse engineering can work properly for both types handled by extensions and those not. +* [Change] Improved the type searching on PgSqlTypeWidget in such a way to display a popup with the data types matching the text typed by the user. +* [Change] Improved TableObjectView to be rendered with/without schema names appended to user-defined data type names. +* [Change] Minor adjustment on icon size of QTreeWidget instances. +* [Change] Improved the NewObjectOverlayWidget in such a way to allow only one action to be executed at a time. +* [Change] Several clean-ups in the source code root. Removed unused files. +* [Change] The subproject libpgmodeler was renamed to libcore and now moved to libs/ +* [Change] The subproject libpgmodeler_ui was renamed to libgui and now moved to libs/ +* [Change] The subproject libobjrenderer was renamed to libcanvas and now moved to libs/ +* [Change] The main executable subproject was renamed to pgmodeler and now moved to apps/ +* [Change] The main-cli executable subproject was renamed to pgmodeler-cli and moved to apps/ +* [Change] The crashhandler subproject was renamed to pgmodeler-ch and moved to apps/ +* [Change] Created a subfolder called "assets" to store all deployed files that aren't libraries or executables: conf, lang, schemas, samples, etc. +* [Change] Refactored all .pro/.pri files in order to reference pgModeler libraries from variables $$LIB[LIBNAME] instead of relative paths. +* [Change] Renamed all icons that were in Portuguese to English. +* [Change] In SnippetsConfigWidget replaced the SQL highlight by Schema micro-language highlighting. +* [Change] Renamed BlockInfo class to TextBlockInfo and moved to a dedicated source file. +* [Change] Changed the workflows to build any *fix, *change, *support branches. +* [Change] Minor improvement on QMainWindow to resize general toolbar buttons. +* [Change] Widgets that were emitting the signal s_visibilityChanged(bool) only on hide event no emit s_hideRequested instead. The s_visibilityChanged(bool) is now reserved to widgets that need to notify visibility changes passing the current state to slots (hidden/displayed) in for of a bool parameter. +* [Change] Minor hint text typos fixes. +* [Change] Improved the syntax error messages in SchemaParser. +* [Change] Minor adjustment in the minimum width of the general toolbar when resizing the buttons. +* [Change] BaseForm::setMainWidget(QWidget *) version will use the same icon as the widget being inserted. +* [Change] Adjusting the general toolbar width according to the screen DPI. +* [Change] Renamed the namespace PgModelerUiNs to GuiUtilsNs. +* [Change] Renamed the namespace PgModelerNs to CoreUtilsNs +* [Change] Source files and ui files in libgui were reorganized by contexts (widgets, tools, settings, utils, dbobjects) +* [Change] Applied an automatic indentation to all schema files. +* [Change] pgModeler will now create missing config files in the startup. +* [Change] Replaced duplicated code that saves files and raises exception by UtilsNs::saveFile +* [Change] The class Schema now has its own id interval (4000 - 4999) in order to make the split code generation be done properly. +* [Change] Minor adjustment in AppearanceConfigWidget to enable scrollbars in the viewport so users on small screens can see the entire model. +* [Fix] Fixed the crash handler and bug report form in such a way to load the last modified model opened before their execution. +* [Fix] Fixed the column positions in ObjectDepsRefsWidget. +* [Fix] Fixed a crash when the database import process fails to create an inheritance relationship somehow. +* [Fix] Fixed a bug in the database import process that not correctly setting up the data type name of columns when the types were handled by extensions. Types handled by extension don't need to have the schema name prepended. +* [Fix] Minor fix in database import process in such a way to properly update the table rendering to hide schema names from title box. +* [Fix] Fixed a malformed SQL code when configuring timestamptz in PgSqlType. +* [Fix] Fixed the reference to libutils in deploy scripts. +* [Fix] Fixed doxygen references for libraries and executables. +* [Fix] Fixed the path to globalattributes.cpp in deploy scripts. +* [Fix] Added missing file windows_ico.qrc. +* [Fix] Fixed a bug in SyntaxHighlighter that was wrongly highlighting the entire document when a multiline group had a line break as the final expression. +* [Fix] Fixed the syntax highligting files (xml, sql). +* [Fix] Minor fix in CLI in order to associate .sch files to the scheditor. +* [Fix] Fixed a bug that was causing all layers to be active even if there was some inactive (invisible) when adding a new layer. +* [Fix] Fixed the method PgModelerCliApp::handleWindowsMimeDatabase to properly insert sch file association in Windows registry. +* [Fix] Fixed the "iCCP: CRC error" in PNGS at libs/libgui/res/icons +* [Fix] Minor fix in SyntaxHighlighter in order to return unformatted word when the group can't be forcibly defined in all exception cases when the word doesn't match any group. +* [Fix] Fixed the description of the option --output in CLI. +* [Fix] Fixed a bug in CLI that could lead to segfault when using diff option and a database model as input. +* [Fix] Fix broken build on Qt 5.11.x. +* [Fix] Minor fix in PgSQLTypeWidget to capture the text changing signal on data type combo so the type format input can be properly updated when the user types the desire data type. + +v0.9.4-alpha +------ +Release date: May 12, 2021
+ +* [New] Added compatibility code that allows loading models created in versions before 0.9.4-alpha without losing layers and active layers information. +* [New] Added an option to the metadata handling operation that serves to indicate if duplicated objects (textboxes, tags, generic sql) must be merged or not. +* [New] Added support for configuration parameters and transform types on functions and procedures. +* [New] Added the compatibility method QtCompat::horizontalAdvance(QFont, QString). +* [New] Added the ability to rename the default layer. +* [New] DatabaseModel now stores in XML code all the new settings related to layers (rect and name colors, rect and names display status). +* [New] Added several methods in ObjectsScene to handle layer colors that helps to save and restore colors from database model files. +* [New] Add support for custom layer colors in LayerConfigWidget. +* [New] Added the class LayerItem to create custom items for displaying layout rects in canvas. +* [New] Added an option to toggle layers rectangles and names from LayerConfigWidget. +* [New] Added support for setup, in general settings, the custom color for grid lines, canvas area and page delimiter lines. +* [New] Added support for multiple layers on the model. +* [New] Added support for PARALLEL attribute to functions. +* [Change] Minor improvement on "Forced filtering" option on ObjectsFilterWidget in order to use a list widget instead of single actions for each object type. +* [Change] Adjusted the default Qt version to 5.15.2 in the deployment scripts. +* [Change] Minor adjustments on Messagebox resizing during first display. +* [Change] Minor improvement on Messagebox in order to display the stack trace toggle button in a more intuitive way. +* [Change] Changed the behaviour of the method ObjectsScene::removeLayers, now it'll allow the resetting or not the layers of the objects. +* [Change] Minor adjustment on QTableWidget vertical header size on DataManipulationForm, ObjectsTableWidget and SqlExecultionWidget. +* [Change] Minor size adjustment policy in the comboboxes in DataManipulationForm, ModelNavigationWidget and ModelValidationWidget. +* [Change] Minor improvement in DatabaseImportHelper::setBaseFunctionAttribs in such a way to discover the name of the functions transform types from their oids. +* [Change] Isolated the duplicated code in DatabaseModel::createFunction and DatabaseModel::createProcedure in the method DatabaseModel::setBasicFunctionAttributes. +* [Change] Adjusted the minimum size of the main window to 640x480 so it can fit in smaller screens. +* [Change] Minor refactoring on SchemaView::configureObject to avoid unecessary calculations when the layers are not visible. +* [Change] Added forced updates of schema rectangles after setting layers to children objects. +* [Change] Change on the search path for PluginsDir to use getPathFromEnv(). +* [Change] LayersConfigWidget will now emit a signal when toggling layer rects/names so the overview widget on mainwindow is properly updated. +* [Change] DatabaseModel will now create a default layer in the constructor. +* [Change] The database model will add the default layer to the loaded model if there isn't a single layer identified. +* [Change] DatabaseModel when loading older database model files will generate random layer colors. +* [Change] The scene now will update layer rects when catching the signal s_objectDimensionChanged from tables and textboxes. +* [Change] Adjust the ObjectsScene to resize layer rects when one or more layers are removed. +* [Change] Improved the window title of DataManipulationForm in sucha a way to display the currently browsed table. +* [Change] Improved the selection of layers to be associated to object in context menu (Quick > Set layers). Now a floating widget is use to select multiple layers for the object selection in the canvas area. +* [Change] Updated the sample models to use "layers" attributes on graphical objects. +* [Change] Changed the value separator for attributes layers and active-layers on from semi-colon to comma. +* [Change] pgModeler CLI will now rename "layer" attributes to "layers" in order to reflect the multiple layers support for older models. +* [Change] Minor copyright updates. +* [Change] The option "Truncate before alter columns" in the diff process was removed since its use is discouraged and dangerous in some situations. +* [Fix] Minor fix in the table's catalog query in order to avoid setting up a partitioning strategy when the table is not a partitioned one. +* [Fix] Minor fix in database import in such a way to update scene layers info before adding it to the main window. +* [Fix] Fixed the layers configuration of example.dbm. +* [Fix] Minor fix in function.sch in order to generate transform types only for PostgreSQL >= 9.5. +* [Fix] Fixed DatabaseModel::getUserDefTypesReferences in such a way to detect that procedures and functions are referencing a user-defined type from their list of transform types. +* [Fix] Fixed ObjectsTableWidget in such a way to control whether the ResizeColsButton can be displayed or not via ObjectsTableWidget::setButtonConfiguration. +* [Fix] Minor fix to avoid black canvas when using settings from 0.9.3 or below on 0.9.4-alpha. +* [Fix] Minor fix in BaseObjectView in such way to avoid the adjustment of its position to the scene grid when the object is not selected. This can avoid undesired adjustment when moving a schema box and having only a portion of its children selected. +* [Fix] Minor fix in ObjectsScene in such a way to update layer rects when the grid alignment option is toggled. +* [Fix] Fixed the buttons shortcuts on LayerConfigWidget. +* [Fix] Minor fix on SchemaView to compute the last position any time the object is reconfigured. +* [Fix] Minor fix in BaseObjectWidget to avoid mark the object as modified in finishConfiguration() before adding it to the parent. +* [Fix] Fixed the key combination to trigger the magnifier tool. +* [Fix] Fixed LayerItem in order to build in Qt 5.9. +* [Fix] Minor fixes in ModelWidget, MainWindow to update scene layer settings correctly. +* [Fix] Fixed the CLI in such a way to update scene layer settings so the exporting processes can generate graphical files correctly. +* [Fix] Minor fix in LayersConfigWidget in such a way to mark the correct active layers when setting up the model to operate on. +* [Fix] Fixed a bug in the layers removal process that was causing objects to be placed in a incorrect layer index after the removal. +* [Fix] Fixed the "Fix" menu in main tool bar. +* [Fix] Fixed a bug in ModelWidget that was causing overlay to be displayed when a textbox object was selected. +* [Fix] Fixed wrong text in collationwidget.ui. +* [Fix] Fixed a bug during the loading of changelog entries. +* [Fix] Fixed the display of warnings during export in ModelExportForm. +* [Fix] Fixed the display of warning messages during export in ModelDatabaseDiffForm. +* [Fix] Fixed a malformed SQL code for triggers. +* [Fix] Fixed typos in README.md. +* [Fix] Fixed the broken build on Qt 5.9.x. +* [Fix] Fixed a bug that was preventing special PKs to be properly configured. +* [Fix] Fixed the SQL generation of functions based on internal language. + +v0.9.3 +------ +Release date: December 30, 2020
+ +* [New] Added support for deterministic and provider attributes in collations. +* [New] Added missing check constraints in the data dictionary. +* [New] Added support for selecting all relationships of a table at once via right-click on a table > select relationships. +* [New] Added extra search fields in ObjectFinderWidget. Now it's possible to search relationships by the involved tables (source and destination table), constraints by their columns (source and referenced columns), and relationships by the foreign keys related to them. +* [Change] The warning message about the unchecked option related to drop missing objects now pops up only when there are partial diff filters configured. +* [Change] Improved the extended fade in/out options for tables/views/foreign tables. +* [Change] The partial diff filters generated from changelog will ignore table children objects in order to avoid the wrong generation of diff code. +* [Change] Minor refactoring in DatabaseModel::addChangelogEntry in order to use new attributes to define changelog operations. +* [Fix] Fixed a crash when trying to select children objects of a schema that has no rectangle defined. +* [Fix] Fixed a crash during the importing of domain objects. +* [Fix] Fixed a crash during the importing of objects into the current model in very specific cases when the model had some tables/views referencing columns added by relationship. +* [Fix] Fixed the full diff switching when there are no filtered objects in ModelDatabaseDiffForm. +* [Fix] Fixed a bug in DatabaseModel::addChangelogEntry that was causing the registration of empty signature for some objects. +* [Fix] Fixed a bug in CLI that was not accepting the use of --list-conns parameter +* [Fix] Fixed the data dictionary generation in such a way to include nextval(sequence) calls in the "default value" column. +* [Fix] Fixed a bug when configuring spatial data types during reverse engineering/diff. +* [Fix] Fixed a bug in Catalog::parseDefaultValues that was causing ARRAY[] values to be wrongly split. +* [Fix] Fixed a bug that was causing infinite validation of imported sequences. + +v0.9.3-beta1 +------ +Release date: October 5, 2020
+ +* [New] Added the version descriptor for PostgreSQL 13. +* [New] Added support for procedures in design, import and diff processes. +* [New] Added support for transforms in design, import and diff processes. +* [New] Added an entry in NewObjectOverlayWidget for procedures. +* [New] Added a custom version of addParameter to Procedure in order to validate the usage of out parameters. +* [New] Added a tool button for transform objects in NewObjectOverlayWidget +* [New] Added a unit test to verify schema files syntax (sql, xml, alter). +* [New] Added the method Cast::setName to override the default behavior of BaseObject::setName. +* [New] Added the class PgModelerUnitTest that must be inherited so the child test class can have access to schema files path. +* [New] Added support for modifying attributes toggler colors from appearance settings. +* [New] Tag objects now include attribute toggler colors. +* [Change] Changed the behavior of the generation of SQL code for database object, now it'll respect the SQL disabled status of the object. +* [Change] The ModelExportHelper will abort the export process if the SQL code of the database object is disabled. +* [Change] The database model is now flagged as modified everytime the objects are swapped. +* [Change] Improved the ObjectSelectorWidget in order to save/restore the geometry of internal ModelObjectsWidget instances. +* [Change] Ajusted the Qt version check in QFontMetricsCompat and QPlainTextEditCompat in order to avoid deprecation warnings. +* [Change] pgModeler will alert about a possible data/work loss if the user is trying to save a model in which there're other instances loaded other tabs. +* [Change] Refactored FunctionWidget in such way to make it a subclass of BaseFunctionWidget. +* [Change] Removing unused method DatabaseModel::removeObject(unsigned,ObjectType). +* [Change] Moved the DTD defintion of parameter tag to a dedicated file to be shared betwen function.dtd and procedure.dtd. +* [Change] Making the class Function be a direct child of BaseFunction. +* [Change] Moved the common code between functions and procedures to a base class called BaseFunction. +* [Change] Replaced the attributes PhysicalTable::DataSeparator and DatabaseExplorerWidget::ElemSeparator usages by PgModelerNs::DataSeparator. +* [Change] Minor improvement on data dictionary in order to add the current year in the footer. +* [Change] ModelExportHelper now is capable of indetifying a transform and procedure objects being exported. +* [Change] Minor fields sizes adjustment in pgsqltypewidget.ui +* [Change] Improved the schema files syntax tests to include all folder under / schemas. +* [Change] Refactored the schema files in order to remove code duplication related to ddl-end token. +* [Change] Minor improvement in ConfigurationForm by adding a splitter between config items (left) and settings page (right). +* [Change] Minor improvements on objects rendering in order to consider screen dpi when configuring objects border sizes. +* [Change] Minor refactoring in the parameter/signature generation in class Function. +* [Change] Making the NewObjectOverlay less transparent in order to enhance reading. +* [Fix] Fixed a bug in constraint.sch that was avoiding the correct importing of exclude of constraints. +* [Fix] Fixed source file name for PgModelerCliApp. +* [Fix] Minor fix in the SyntaxHighlighter in order to highlight correctly multline blocks (specially comments). +* [Fix] Fixed a bug in DatabaseImportHelper that was causing failure when importing some objects' permissions. +* [Fix] Minor fixes on the CLI menu. +* [Fix] Fixed a bug on MainWindow that was wrongly showing the main menu bar in certain cases at startup. +* [Fix] Minor fix in BaseFunction::createSignature in order to remove OUT keywords from signature. +* [Fix] Fixed a bug when importing triggers in which functions arguments contain json/jsonb values. Now values are properly formatted. +* [Fix] Fixed a bug in XmlParser::convertCharsToXMLEntities that was not converting json/jsonb default values correctly breaking the entire XML code of the database model. +* [Fix] Fixed a bug in Parameter class that was causing default values to be ignored. +* [Fix] Fixed a bug in SchemaParser related to exceptions being raised wrongly in expressions evaluation. +* [Fix] Fixed the objects style template config files. +* [Fix] Removed some deprecation warnings when building on Qt 5.15.1. +* [Fix] Fixed a bug in ModelFixForm that was passing arguments to CLI in wrong format. +* [Fix] Minor fix in some project files to remove unnused include paths. +* [Fix] Fixed a bug in CLI that was ignoring input-db parameter when doing diff. +* [Fix] Minor fix in the graphical objects rendering in 4k screens when QT_AUTO_SCREEN_SCALE_FACTOR is set to. Now they are rendered in acceptable proportions. +* [Fix] Minor fix in ModelsDiffHelper in order to avoid generating ALTER...ADD COSTRAINT related to constraints (check and unique) in which parent table is also being created. + + +v0.9.3-beta +------ +Release date: July 10, 2020
+ +* [New] Added GitHub actions scripts in order to test the building on each platform. On Linux and macOs the build will occur on all Qt versions from 5.15 to 5.9, on Windows the build happens only on Qt 5.15 (due to the usage of msys2 that uses the most recent version of the framework). +* [New] Added default constructors in the form "Class(const &)" for Connection, Parameter and TypeAttribute in order to avoid deprecated-copy warnings on GCC9. +* [New] The CLI now validates the mixing of options of different operation modes. +* [New] Added support for partial diffs between a model and database or between two databases. +* [New] Created an internal changelog on DatabaseModel to register object's modification over time being useful for partial diff operations. +* [New] Added the widget called ChangelogWidget to control the model's internal changelog settings in the design view. +* [New] Added support for save/load changelog from model file. +* [New] The CLI now supports partial diffs too. +* [New] Create the method ModelsDiffHelper::getRelationshipFilters. +* [New] Added a warning message prior to the partial diff without using "Do not drop missing objects" option. +* [New] Created a method ObjectsFilterWidget::setModelFilteringMode that disables some options when the filtering widget is being used to filter database model objects. +* [New] Added cast and user mapping to the list of filterable objects. +* [New] Added a hint text in ObjectsFilterWidget to inform about exact match searching. +* [New] Added the methods Catalog::clearObjectFilter and Catalog::clearObjectFilters. +* [New] Added support for DatabaseImportHelper to create a sequence assigned to a column via default value if automatic dependencies resolution is enabled. +* [New] Created the namespace QtCompat that will reunite all the specific code that isn't compatible between different Qt versions. The goal of this namespace is to store in a central point all the code that uses QT_VERSION_CHECK to perform different operations depending on the current Qt version. +* [New] Added the method SchemaParser::getExpressionResult in order to perform comparisons between QVariant values correctly due to the QVariant operators deprecation in Qt 5.15. +* [New] Added the signal ObjectsFilterWidget::s_filtersRemoved that is emitted whenever all filters are removed. +* [Change] Modified the script wingetdate.bat in order to return the build number based on the current local date correctly and renamed it to getbuildnum.bat. +* [Change] Updated to 5.15 the Qt version used by default in linuxdeploy.sh and macdeploy.sh. +* [Change] Replacing verbose QString() calls by "" for string initialization purposes. +* [Change] Improved the sequences assignments to columns in DatabaseImportHelper::assignSequencesToColumns. +* [Change] Improved the method ModelsDiffHelper::setFilteredObjects in order to treat tables/view/foreign tables properly by appending their children objects to the creation order list of filtered objects. +* [Change] Adjusted the Catalog::setObjectFilters in order to configure exact match filters when any wildcard filter provided has no *. +* [Change] Adjusted the partial diff process between a model and a database in which there's one or more many-to-many relationships filtered. +* [Change] Minor adjustment on objects grids in SwapObjectsIdsWidget, DatabaseImportForm and ModelDatabaseDiffForm by changing the columns order. +* [Change] Improved the method ModelsDiffHelper::setFilteredObjects in order to detect the proper creation order of the provided objects. +* [Change] Minor change in ObjectsFilterWidget by making the action "Only matching" checked by default. +* [Change] Minor improvement on CLI to accept the value "all" for the paramenter --force-children in order to force all table children at once. +* [Change] BaseObject::configureSearchAttributes now configures the signature attribute as a formatted string. +* [Change] Minor improvement on ObjectFinderWidget::updateObjectTable in order to optionally create checkable items in the first column. +* [Change] Attributes related to object filters were moved from Catalog to PgModelerNs in order to be shared between Catalog and DatabaseModel classes. +* [Change] Minor improvement in Connection::getConnectionId in order to return an optional HTML formatted string. +* [Change] Isolated the method DatabaseImportForm::listFilteredObjects in a static one in order to reuse it on ModelDatabaseDiffForm. +* [Change] Improved the objects filtering in such way to allow filter by name or signature. +* [Change] Improved the UI of ObjectsFilterWidget by moving all options to a popup menu. +* [Change] Several changes in all catalog queries in order to support signature matching. +* [Change] Minor adjustemnt in Catalog::getFilterableObjectNames. +* [Change] Adjusted the appimages building process. +* [Change] Changing the default font size of graphical objects to 10pt in order to try to solve the intermittend issue of disappearing texts. +* [Change] Updated the French translation. +* [Fix] Fixed a regression in ObjectFinderWidget that was not opening objects form with double-click on an item on the results grid. +* [Fix] Fixed a bug when drawing relationships in FK to PK connection mode. Now when one of the tables is collapsed the center points of both are used as connection points to the relationship. +* [Fix] Fixed a crash in ModelDatabaseDiffForm while enabling/disabling the partial diff tab. +* [Fix] Fixed the diff process for inheritance relationships created for two existing tables. +* [Fix] Fixed a crash in LayersWidget when renaming a layer. +* [Fix] Minor fix in DatabaseImportHelper::assignSequencesToColumns. +* [Fix] Fixed a wrong comparison in Catalog::getObjectsOIDs. +* [Fix] Minor fix in ConstraintWidget that was trying to validate FK relationships for generated tables of many-to-many relationships. +* [Fix] Fixed a bug in Catalog::getObjectsOIDs that was executing a catalog query for a certain object when it was not being filtered. +* [Fix] Minor fix in ModelDatabaseDiffForm tabs enabling/disabling steps. +* [Fix] Fixed the QProcess usage in ModelFixForm due to QProcess::start() deprecation in Qt 5.15. +* [Fix] Fixed a crash when trying to move several objects to a layer from the object finder widget and in the selected set one or more objects aren't graphical ones. + +v0.9.3-alpha1 +------ +Release date: May 20, 2020
+ +* [New] Added support for creating initial configuration files from CLI. +* [New] The CLI is now capable of using the objects filtering in reverse engineering. +* [New] Added a warning message when trying to import a big database. +* [New] Added support for object filtering in reverse engineering dialog. +* [New] Adding support for AppImage building for Linux. +* [New] Added support for importing PostgreSQL 12 generated columns. +* [New] Adding support for PostgreSQL 12 generated columns. +* [New] The ModelNavigationWidget now will display a save icon if the current model is pending a save operation. +* [New] pgModeler now guesses if a FK relationship consists in a one-to-one based upon the foreign keys and unique keys settings. +* [New] Improved the rendering of FK relationships. Now it recognizes the minimum cardinality by using the right crow's foot descriptor o|< or ||< in the destination entity. +* [New] Added support for the conversion of 1-1 and 1-n relationships, allowing the user to perform modifications over objects generated by those relationships. +* [New] Added "virtual" keyword in classes that inherit others so the destruction order can be followed correctly. +* [New] Adding support for copy model validation widget output as text as well preview it as texts. +* [New] Added support for show/hide all layers in LayersWidget. +* [New] Added the paramenter application_name to Connection in order to indentify connections created by pgModeler when querying pg_stat_activity. +* [New] Added support for save/restore Z value attribute in MetadataHandlingForm. +* [New] Created an improved and reusable file selector widget. +* [Change] Improvements done in DatabaseImportHelper in order to speed up the listing of types as well the importing user-defined types on demand. +* [Change] Refactored the way default value fields states are setup by user's actions. +* [Change] Adjusted the default size of DatabaseImportForm. +* [Change] Avoiding retrieve all types (system and user defined) at once before the reverse engineering in DatabaseImportHelper (Experimental). +* [Change] Minor improvement on DatabaseImportHelper in order to display the correct message while assingning sequences to columns. +* [Change] Improved the catalog queries in order to retrive parent oids and type when using the list queries. +* [Change] Minor updates on windeploy.sh and macdeploy.sh +* [Change] Minor improvement on DatabaseImportHelper in order to speed up the objects creation. +* [Change] Improved the execution time for the catalog query of data types. +* [Change] Improved the catalog query for sequences. +* [Change] Avoiding the diff process to generate default value changes for generated columns. +* [Change] Minor improvement on DatabaseModel::validateRelationships. +* [Change] Improved the ModelWidget::convertRelationship1N() in order to avoid segfaults in certain cases. +* [Change] Minor adjustment in PhysicalTable::restoreRelObjectsIndexes in order to diminish memory usage. +* [Change] Minor improvement on update icon. +* [Change] Minor improvement in LayersWidget in order to allow manual resizing using the mouse. +* [Change] Improved the following classess in order to use the new file selector widget: ModelExportForm, ModelFixForm, MetadataHandlingForm, ModelDatabaseDiffForm, GeneralConfigWidget, PluginsConfigWidget, CsvLoadWidget, CrashHandlerForm and BugReportForm. +* [Fix] Minor fix in OperationList in order to update FK relationships related to FKs that contains the column being handled by the list. +* [Fix] Fixed a bug when retrieving the refs to some objects in DatabaseModel. +* [Fix] Minor fix in CLI menu and error messages. +* [Fix] Fixed the role importing process. Now referenced roles are auto resolved. +* [Fix] Fixed the dependency checking for user defined types in DatabaseModel. +* [Fix] Fixed a bug when loading extension that has no schema specified. +* [Fix] Minor fix in DatabaseImportHelper::createFunction in order to solve eventual duplicated parameter names when importing some functions. +* [Fix] Fixed a bug that was causing global name patterns for relationships to never be used even if they were properly configured. +* [Fix] Minor fix in ModelObjectsWidget and ModelWidget to provide the correct information about objects' selection in SceneInfoWidget. +* [Fix] Fixed a bug in RelationshipWidget that was causing the cursor never to be restored to its original icon when an exception occurred during relationship editing. +* [Fix] Fixed a crash in some situations when closing models. + +v0.9.3-alpha +------ +Release date: March 26, 2020
+ +* [New] Added support for multiselection in ModelObjectsWidget. +* [New] Added an optional parameter in PgModelerNs::generateUniqueName to avoid comparing the input object. +* [New] Added support for objects' bulk renaming. +* [New] Added support for multiselection in ObjectFinderWidget. +* [New] Added support for middle button click on source code panel in order to paste the selected code in the current open SQL execution widget. +* [New] Using the CRTP (Curiosly Recurring Template Pattern) approach to create a template type based on BaseType in such way that the static member from that template but used on all derived classes of TemplateType can be unique for each derived class. +* [New] Added a "Stacking" action in popup menu that is used to control the z value of graphical objects. +* [New] Adding support for move objects on the Z stack up and down. +* [New] Added support for CLI to write system wide mime database on Linux and Windows. +* [New] Added a method GlobalAttributes::setSearchPath so the application can setup the path in which the internal folders (schemas, lang, etc) can be found. +* [New] Added the ability to remove owners from objects from Quick Actions > Change owner. +* [New] Added an fix step that removes IN keyword from functions signatures. +* [Change] Refactored the method DatabaseModel::getObjectDependecies by splliting it into small portions that handles specific object types dependecies. +* [Change] The DatabaseModel::getObjectReferences was splitted in other get[object]References() in order to facilitate maintainance. +* [Change] Minor adjustments in order to make the objects listing a bit faster for large databases. +* [Change] Minor improvement on ObjectRenameWidget in order to apply renaming in reverse id order of the object so objects invalidations (due to relationships revalidations) diminishes. +* [Change] In DatabaseModel the invalidated special objects are now stored in a list which is destroyed only when the model is destroyed too. This will avoid segfaults in some cases when the objects in that list are still being referenced in the operation list (Experimental). +* [Change] Minor adjustment in ModelObjectsWidget and ObjectFinderWidget in order to emit the signal ModelWidget::s_sceneInteracted so the left menu at MainWindow can be updated accordingly. +* [Change] Minor change in PgModelerNs::generateUniqueName in order to remove quotes from names before perform the comparison. +* [Change] Refactored ObjectRenameWidget in order to support multiple objects renaming. +* [Change] Refectored all the classes derivated from BaseType moving them to dedicated sources files in order to make them reuse TemplateType class isolating the related keywords, improving maintainance. +* [Change] Removed the class LanguageType since it was replaced by namespace DefaultLanguages namespace. +* [Change] Isolated the default language names into a namespace called DefaultLanguages and removed any reference to LanguageType in the code. +* [Change] Improved the DataManipulationForm in such way that the user can sort results by clicking the column names in the result grid. This will cause a new query to be performed by using the clicked column as sorting criteria. +* [Change] The current model's popup menu is now used as the "More" actions menu at MainWindow > general toolbar. +* [Change] Refactored the ModelWidget::configurePopupMenu separating some portions in new methods to make maintainance more easy. +* [Change] Moved the 'Fix model' and 'Objects metadata' actions to the general toolbar (left) at main window under the menu "Fix". +* [Change] The class HintTextWidget was removed and replaced by simple html QToolTips. +* [Change] Small change in the icon related to new tab opening in SQLToolWidget. +* [Change] Minor adjustment or rows resizing policy on datamanipulationform.ui. +* [Change] Minor adjustment on updatenotifierwidget.ui to allow link opening. +* [Change] Refined the installer wizard pages. +* [Change] Improved the installer script to work better on Windows. +* [Change] Improving the installer on Linux and Windows to select the installation for all users or current user. +* [Change] Improved the linuxdeploy.sh in order to remove the need to use the startup scripts by the binaries in the installer. +* [Change] Fixed the installscript.qs in order to correctly update the mime database on Linux. +* [Change] Minor improvements on the usability of swap objects ids form. +* [Change] Separated the code that handles mime db on linux and windows, using a #ifdef switch to call the correct method depending on the platform. +* [Change] Adjusting the linker options to make the executables search for libraries in PRIVATELIBDIR without forcing the usage of LD_LIBRARY_PATH. +* [Change] The class Application was moved to libutils and has a basic implementation of just initialize the search path on GlobalAttributes. +* [Change] Rename the classes Application and PgModelerCli to respectively PgModelerApp and PgModelerCliApp and they now inherits the new Application class in order to take advantage of the GlobalAttributes::setSearchPath. +* [Change] The crash handler application is now executed under a Application instance not a QApplication anymore in order to use GlobalAttributes::setSearchPath. +* [Change] Changed the namespace GlobalAttributes to a singleton in order try to solve problems with fallback paths. +* [Change] Updated deployment scripts to use Qt 5.14.x +* [Change] Changing the exposed main window from QMainWindow to MainWindow in PgModelerPlugin interface. +* [Change] Moved the method SchemaParser::convertCharsToXMLEntities to XmlParser. +* [Change] Minor buttons position adjustments on WelcomeWidget. +* [Change] Minor refactoring on OperationListWidget in order to show a more compact text when displaying operations done over objects. +* [Change] Removed the workaround code that disables the ALTER SET OWNER when the role associated to it is disabled and the object itself not. The best approach is to dissociate the role from the object so the ALTER instruction is not generated. +* [Fix] Fixed a shortcut duplication in DatabaseExplorerWidget +* [Fix] Fixed the shortcut for partitioning relationships in new object overlay +* [Fix] Fixed a minor bug in MainWindow that was causing the bottom widgets bar to be displayed even when object finder widget and model validation widget weren't visible. +* [Fix] Fixed a bug that was causing copy options to stay hidden for copy relationships in the relationship form. +* [Fix] Fixed the importing of extensions on PostgreSQL 9.4 and below. +* [Fix] Fixed the name uniqueness generation when the name is truncated when exceeding 63 bytes. +* [Fix] Fixed a bug that was preventing the recent menus cleaning to be persisted in the conf file. +* [Fix] Fix a bug in the validation of collation objects. +* [Fix] Fixed a crash in ObjectRenameWidget when renaming several objects in which there was the need to revalidate relationships; +* [Fix] Fixed the method PgSqlType::getTypes in order to avoid returning the first (null) type. +* [Fix] Fix the importing/diff of columns based on PostGiS data types. +* [Fix] Fix a crash in UpdateNotifierWidget when compiling pgModeler using Qt 5.14.x. +* [Fix] Minor fix in PgSQLTypeWidget to avoid show an error message box when the user types an invalid data type name. +* [Fix] Additional fix on XmlParser::convertCharsToXMLEntities in order to replace special char to xml entities correctly. +* [Fix] Minor fix in the update notifier widget display position. +* [Fix] Minor fix in diff regarding to the comparison on column/domain default values. Now the values are compared in insensitive case. +* [Fix] Fixed the Windows installer in order to create the start menu item correctly (system wide). +* [Fix] Minor fix on CLI in order to allocate export/import/diff helpers and config widgets only when they are required (when one of the options related are used). +* [Fix] Fixed a bug that was allowing the applying changes of the forms on relationship added objects by hitting ENTER causing crashes. +* [Fix] Fixed the bug that was causing model restoration to be displayed when the application was started from a double click on a model file. +* [Fix] Fixed a bug in the metadata handling that was not restoring the collapse mode of tables. +* [Fix] Fixed a crash on UpdateNotifierWidget after upgrading to 5.14. A wrong deletion was being performed where deleteLater() needed to be used instead +* [Fix] Removing lots of Qt 5.14 deprecation warnings in the code. +* [Fix] Fix a bug that was causing wrong replacements during the reverse engineering of functions. +* [Fix] Fixed the method XmlParser::convertCharsToXMLEntities in order to avoid chars replacements within Release date: December 26, 2019
+ +* [New] Add support for data dictionaries generation in HTML format in ModelExportForm. +* [New] Added options to control data dictionary generation in CLI. +* [New] Plugins now can optionally be associated to a menu action or not. Generally, an plugin not associated to a menu action is automatilly executed during the startup (see PgModelerPlugin::initPlugin). +* [New] Added a missing model fix step on CLI that removes the IN keyword from functions signatures. +* [Change] Making BaseRelationship::getReferenceForeignKey() public. +* [Change] Isolated duplicated code in MainWindow::isToolButtonsChecked that checks if any tool button of the bottom or right widget bars is checked. +* [Change] Removing the plugins from core code. +* [Change] Modified pgmodeler.pro to include plugins folder when present in the source root (either in debug or release mode). +* [Change] Ignoring plugins folder in the core code. +* [Change] Minor improvement on ModelWidget::rearrangeSchemasInGrid in order to consider the amount of tables to determine the minimum grid size used to rearrange table. +* [Change] Minor text adjustments in CLI. +* [Change] Added an additional checking during relationship creation in order to avoid the creation of 1-* or n-n relationships involving partition tables. +* [Change] Removing the restriction to create 1-1, 1-n and n-n relationships in which the involved tables are partitioned ones. +* [Change] Disabling the SQL statment ALTER...OWNER TO in the object's SQL when the owner role has its SQL disabled but the object itself not. This will avoid reference errors when validating/exporting code. +* [Fix] Fixed the "Save" action enabled state according to the current model's modified state. +* [Fix] Fixed a crash when the user tried to edit connections in ModelDatabaseDiffForm and right after select a connection in the "Compare to" field. +* [Fix] Fixed the generation of escaped comments for columns. + +v0.9.2-beta2 +------ +Release date: November 1st, 2019
+ +* [New] Added support for foreign tables. +* [New] Added the method DatabaseModel::getObject(QString,vector) to return the first ocurrency in the lists related to the provided types. +* [New] Added support for select all foreign tables in ModelWidget. +* [New] Created the method BaseTable::isBaseTable to help determining if an object type is of Table, View or ForeignTable. +* [New] Added extra support for foreign tables on DatabaseExplorerWidget and DataManipulationForm. +* [New] Added the method DatabaseImportHelper::createColumns in order to isolate the code to create table/foreign table columns during reverse engineering. +* [New] Added support for foreign table importing as well its children objects (columns, constraints, triggers). +* [New] Added server and options fields on TableWidget for foreign table. +* [New] TableWidget now fully supporting the edition of foreign tables. +* [New] Added the ability to TableView to render ForeignTable objects. +* [New] Added support for swap objects ids using arrow keys by changing creation order between two close objects on the grid. +* [New] Added support for save diff settings in form of presets. +* [New] Added an option to BaseObject to force the comment escaping making multilined comments be presented as single lines but without changing their semantics. +* [New] Adding support for parse escaped text delimiters and value separators in CSVLoadWidget. +* [Change] Avoiding the usage of "Generate ALTER commands" option when the table is a partition or partitioned. +* [Change] Avoid unchecking PK checkboxes on TableWidget when adding a new column. +* [Change] Validating the dialogs geometry regarding to screens geometry in order to avoid their appearance in an invalid position (out of range). +* [Change] Limiting the size of the exceptions stack in 50 elements. +* [Change] Improved the GenericSQL::isObjectReferenced in order to check if, when a referenced object is a column, the provided object is the same as the parent of that referenced object. +* [Change] Restricting the usage of "Default partition" option for partitioning relationships when the partition table is a foreign table. +* [Change] Making ModelObjectsWidget update the foreign table subtree. +* [Change] Making ReferenceWidget to use foreign tables from referenced table selector. +* [Change] Improved the Relationship class to accept foreign tables. +* [Change] Improved the DatabaseModel::getObjectDependecies and DatabaseModel::getObjectReferences to include ForeignTable. +* [Change] Updated View class to accept reference foreign table columns. +* [Change] Moved the original implementation of DatabaseModel::createTable to a template method createPhysicalTable in order to reuse it to create tables and foreign tables. +* [Change] ForeignObject is not a BaseObject child anymore due to multi inheritance problem that it can generate in ForeignTable class. +* [Change] Minor ajustment in Relationship class to accept PhysicalTable in its constructor so relationships can be used by ForeignTable class as well. +* [Change] Isolated the code common to Table and ForeignTable classes in a parent class named PhysicalTable. +* [Change] Disabling mime type update on installers. +* [Change] Minor adjustment on SQLExecutionWidget::generateBuffer to escape line breaks and separators when generating CSV buffer. +* [Change] Removing unused code from NumberedTextEditor. +* [Change] Changed the way temp source file is handled by the tool in order to solve a sharing violation problem on Windows. +* [Change] Minor adjustment on HtmlItemDelegate to avoid creating local variables in paint() everytime the method is called. +* [Fix] Fixed an bug in SQL generation of columns that was wrongly removing a comma from decimal data types. +* [Fix] Fixed some catalog queries in order to support PostgreSQL 12. +* [Fix] Fixed ObjectsScene to remove foreign tables during destruction. +* [Fix] Fixed the View::getObjectCount in order to return 0 when the provided object type is invalid. +* [Fix] Fixed the ObjectFinderWidget in order to fade out correctly the listed/not listed elements. +* [Fix] Fixed the quick actions menu at ModelWidget in order to include the "Edit data" action for foreing tables. +* [Fix] Fixed the DatabaseImportHelper::assignSequencesToColumns in order to correctly assign sequences to foreign table columns. +* [Fix] Fixed a crash in ModelValidationHelper that was caused by wrong checking when validating generic sql objects. +* [Fix] Fixed the source code display for tables and foreign tables on DatabaseExplorerWidget. +* [Fix] Fixed the CodeCompletionWidget to display foreign table children. +* [Fix] Fixed the loading of generic SQL objects when a referenced object was a column. +* [Fix] Additional fixes to correctly reference foreign tables and tables in the portions were both classes are acceptable/desirable. +* [Fix] Fixed the diff process in order recognize partition foreign tables attach/detach. +* [Fix] Fixed the generation of XML code of partitioning relationships. +* [Fix] Fixed the Relationship::getAlterRelationshipDefinition to include foreign tables. +* [Fix] Fixed the preset.sch since it was not registering the "Reuse sequences" options correctly. +* [Fix] Improved the DataManipulationForm in order to restore the columns visibility when retrieving again the data of the current table. +* [Fix] Fixed the drop action in DatabaseExplorerWidget for user mappings. +* [Fix] Fixed the ModelWidget::rearrangeTablesInGrid to adjust position of foreign tables. +* [Fix] Fixed the generation of SQL code of partition tables in order to avoid the inclusion of partitioned tables columns on the code. +* [Fix] Fixed a crash on DatabaseImportHelper when destroying detached inherited columns. +* [Fix] Fixed the object duplication operation in model widget to accept duplicate foreign table children objects. +* [Fix] Fixed the creation of relationships involving foreign tables. +* [Fix] Fixed the permission object in order to support foreign tables. +* [Fix] Fixed the model export helper to support foreign tables. +* [Fix] Fixed ModelWidget to show missing popup actions for foreign tables. +* [Fix] Fixed the NewObjectOverlayWidget to display tool buttons related to foreign table children. +* [Fix] Fixed the SchemaView::fetchChildren to include foreign tables in the returned list. +* [Fix] Fixed the ModelValidationHelper to validate foreign tables and table-view relationships. +* [Fix] Fixed ColumnWidget and ConstraintWidget to accept foreign tables usage. +* [Fix] Fixed a regression when importing permissions related to functions. +* [Fix] Fixed the OperationList to handle foreign tables. +* [Fix] Fixed create methods in DatabaseModel related to table children object in order to accept foreign tables. +* [Fix] Fixed the SwapIdsWidget postion/size saving and restoration. +* [Fix] Minor tooltip fix in GeneralConfigWidget. +* [Fix] Minor fix in default conf files removing unused tag attribute. +* [Fix] Additional fix to the extension import to correctly indetify it as a data type handler. +* [Fix] Fixed a bug on Role's SQL generation due to a missing attribute. +* [Fix] Additional fix in GeneralConfigWidget to save correctly the settings of dockwidgets. +* [Fix] Minor fix in DatabaseModel to write ddl end token in the appended/prepended custom code. +* [Fix] Fixed a false-positive result when doing the diff between two fuctions that contains the same signature. +* [Fix] Fixed the diff generation for Role objects when setting up an blank password. +* [Fix] Fixed the "Prepend at the beggining of the model" option behavior on CustomSQLWidget. +* [Fix] Fixed the catalog query for extension in order to indetify correctly if this object handles a data type. +* [Fix] Fixed the Variadic option enabling on ParameterWidget. +* [Fix] Fixed the saving of validator widget settings. There was a conflict between pgsql-ver attributes present on the validator settings and the default attribute added by the schema parser. The solution was to use a different attribute (version) in the validator. +* [Fix] Fixed the "Clear items" action in popup menu at DataManipulationForm. +* [Fix] Fixed the importing of tables and views in such way to automatically create correctly the domains referenced by their columns. +* [Fix] Fixed a bug on ModelDatabaseDiffForm that was causing the form to be reseted on the middle of a diff process when the user minimize the diff dialog causing unexpected behavior (or even crashes sometimes). +* [Fix] Minor fix in AboutWidget. +* [Fix] Minor fix in ModelDatabaseDiffForm to avoid using uniform items height in output widget. + +v0.9.2-beta1 +------ +Release date: September 2, 2019
+ +* [New] Added a routine to write a backup file during the saving of model files in order to avoid data loss in some rare cases. +* [New] Added a new action on DataManipulationForm to clear the selected items by pressing Ctrl+R. +* [New] Enabling/disabling the save model action according to the model's modified status. +* [New] The main window instance is now exposed to plugins to make the extra features development more flexible. +* [New] Avoiding selecting table items in BaseTableView::mousePressEvent which doens't contain an underlying (source) object. +* [New] Adding support for duplicate several table objects at once. +* [New] Added support for table children multiselection by using Ctrl+Shift+Click on them. +* [New] Added support for load the generated diff code in the SQL tool and automatically browsing the destination server for manual diff applying. +* [New] Added a button to create a new data manipulation form from within another data manipulation form. +* [New] Added a confirmation message before closing a database explorer widget. +* [Change] Minor adjustments in PgModelerUiNs::createOutputListItem and PgModelerUiNs::createOutputTreeItem to better display formatted messages. +* [Change] Minor improvement on CSV text copying to exclude from the buffer the hidden columns. +* [Change] Adjusted the font weight on WelcomeWidget (only for Linux). +* [Change] Minor adjustment on tool buttons font size on DataManipulationForm. +* [Change] Improved the UI of the DataManipulationForm by rearranging the tool buttons to the left of the dialog. +* [Change] Improved the clipboard text pasting on DataManipulationForm in order to parse the text as CSV when Ctrl+Shift+V is pressed. +* [Change] The filter input on SQLExecutionWidget is now automatically focused when toggling the filter widget. +* [Change] Changed the default behavior of result set filtering to Qt::MatchContains on SQLExecutionWidget. +* [Change] Avoiding showing the "Swap ids" action in popup menu when we have only columns/constraints selected +* [Change] Minor adjustment on SceneInfoWidget to avoid display dimensions of selected columns/constraints on the canvas. +* [Change] Renamed the method BaseGraphicObject::getReceiverObject to getOverlyingObject (to make sense with its counter part BaseObjctView::getUnderlyingObject) +* [Change] Avoiding clear the whole scene selection when the table is already selected and the user requested popup menu. +* [Change] Renamed BaseObjectView::getSourceObject to getUnderlyingObject. +* [Change] Improved the object protection action in ModelWidget in order to accept the multi item selection on tables. +* [Change] Changed the way the PSVI attribute is handled in xmlparser to retrieve big line numbers on a xml document. +* [Change] Improved the diff code preview allowing the user to close the dialog without going back to previous tab and click 'Cancel'. +* [Change] Minor adjustment on buttons shortcuts/tooltips on DataManipulationForm. +* [Change] Changed the way the model saving timers are controlled to avoid infinity savings on the model (when the auto saving option is disabled) making the application unusable. +* [Change] Making the mime update operation return exit code 0 even if there was errors (still displayed in the console). This will avoid the installer to abort installation when the dbm mime update fails. +* [Change] Avoiding applying fillfactor to gin indexes. +* [Change] Moved the method DatabaseImportHelper::parseIndexExpressions to Catalog class. +* [Fix] Fixed a broken diff code generation for policies. +* [Fix] Fixed the object duplication action when only a single table object is selected. +* [Fix] Fixed a bug in ModelWidget::removeObjects that was causing the removal of relationship added columns +* [Fix] Fixed the ModelWidget::configurePopupMenu to consider the table's multi item selection. +* [Fix] Fixed a false-positive diff result when dealing with timestamptz. +* [Fix] Fixed the progress calculation of dbm files loading. +* [Fix] Fixed a bug that was causing the generation of broken view code. +* [Fix] Fixed the display of index expressions on DatabaseExplorerWidget. +* [Fix] Minor fix on SQLExecutionWidget to avoid results grid to overlap command execution history widget in certain cases. + +v0.9.2-beta +------ +Release date: May 31, 2019
+ +* [New] Added support for user mapping. +* [New] Added support for foreign server. +* [New] Added support for foreign data wrapper. +* [New] Added support for reduced verbosity on diff, export and import processes in order to improve performance. +* [New] Adding missing tootip on ObjectFinderWidget. +* [New] Generic SQL objects now support dynamic references to objects which can be used in the definition code. +* [New] Added support for compare foreign servers on diff process. +* [New] Created a generic getAlterDefinition on ForeignObject. +* [New] Added ForeignServer toolbutton in NewObjectOverlayWidget. +* [New] Added support for the reverse engineering user mapping objects. +* [New] Added support for the reverse engineering foreign server objects. +* [New] Added code snippets for foreign data wrapper and foreign server. +* [New] Added support for diff user mapping. +* [New] Added support for diff foreign data wrappers. +* [New] Added support for set permissions to foreign data wrapper. +* [New] Added the WRAPPER, SERVER and MAPPING key words to sql-highlight.conf. +* [New] Added the method PgSqlType::isExactTo in order to do a full comparison (all attributes) between two data types. +* [New] Added the ability to view references to store referenced tables. This feature will cause relationships to be created between the view and the referenced tables. This is useful when we're using reverse engineering feature in which, in previous versions, couldn't determine the tables that were linked to a view. Now, with this feature a relationship is created between the view and all involved tables. +* [New] Added missing data type macaddr8. +* [New] Enabling quick clear button on several input fields. +* [New] Added support for result set filtering in the SQL execution widget. +* [New] Adding a column labeled "Comment" in TableWidget and ViewWidget to hold comments of children objects. +* [Change] Changed the shortcut of run SQL action in SQLExecutionWidget to F5. +* [Change] Changed the shortcut of tree update action in DatabaseExplorerWidget to F6. +* [Change] Change "New object" action in popup menu in order categorize object types when clicking the database object diminishing the amount of items displayed on the screen. +* [Change] Improved the object search mechanism in such way that various attributes of the object can be matched. New searchable attribute may be added in the future. +* [Change] Added missing code documentation. +* [Change] Minor adjustment on ForeignDataWrapper::getAlterDefinition. +* [Change] Minor improvement on ModelDatabaseDiffForm to show the connection id of the databases being imported in the output tree. +* [Change] Formatting server objects' attributes on DatabaseExplorerWidget. +* [Change] Minor adjustments on the icons of the buttons in ObjectsTableWidget. +* [Change] Improved the method DatabaseModel::getObjectReferences to detected foreign data wrappers as functions' references. +* [Change] Minor code refactoring on Table and View classes. +* [Change] Renamed the method Exception::getErrorType to Exception::getErrorCode. +* [Change] Improved the ModelValidationWidget in such way that is possible to operate over objects on the output list through their respective context menu (the same as in the ModelWidget). +* [Change] Now its possible to trigger the swap ids dialog for two selected objects, causing their ids to be swapped more quickly. +* [Change] Minor refactor on schema files. +* [Change] Minor attributes refactoring on several classes. +* [Change] Minor change in the PgSqlType constructor by turning some parameters optional in order to facilitate the creation of array only types. +* [Change] Minor update on disclaimer text at start of the source files. +* [Change] Allowing copied object to be pasted multiple times. This feature works only with copy/paste operation without remove the pasted objects from the clipboard, for cut/paste the behaviour is unchanged. +* [Change] Increased the maximum limit of SQL history. +* [Change] Updated the windeploy.sh and the installer scripts. +* [Change] Adjusted the installer scripts. +* [Change] Changed the windows deploy script to use Qt Installer Framework. +* [Change] Adjusted the deploy script to use Qt 5.12. +* [Change] Fixed the windows deploy script to use newer version of the compiler in 64 bits environment. +* [Change] Minor improvements in SQLToolWidget and SQLExecutionWidget to avoid segmentation faults when trying to close a execution tab while the command is still running. +* [Change] Adjusted the resize parameters in DataManipulationForm to avoid wrong dialog resizings mainly on Windows. +* [Fix] Fixed a bug in DataManipulationForm that was deleting new rows wrongly. +* [Fix] Fixed a bug that was causing domain constraints not to be extracted correctly during reverse engineering. +* [Fix] Fixed a bug that was causing a fk relationship not to be deleted if the fk tied to it was changed by the user. +* [Fix] Fixed a bug on CLI that was not fixing broken models correctly when they had no role declaration. +* [Fix] Fixed a bug that was causing tables not to be moved on the canvas using mouse. +* [Fix] Fixed a crash related to destruction of special objects on DatabaseModel::destroyObjects. +* [Fix] Fixed a bug that could crash the application when no language was specified to a funcion and the SQL/XML code was being generated. +* [Fix] Minor fix a bug on index importing. +* [Fix] Minor fix on View::isReferencingTable. +* [Fix] Fixed a crash when a query executed in SQLExecutionWidget was a DDL one or was not returning results. +* [Fix] Fixed a bug in CLI that was failing to fix model in certain cases. +* [Fix] Minor fix on buttons tooltips. +* [Fix] Fixed a bug that was causing syntax error if the last column of a table had the SQL code disabled. +* [Fix] Fixed a bug on diff process due to a missing attribute on the generation of diff code for inheritance relationships. +* [Fix] Fixed a bug when rendering several self relationships attached to the same table. +* [Fix] Fixed the CLI in order to restore the layers information when fixing a broken model. +* [Fix] Fixed a bug in object finder that was causing objects from a hidden layer to be displayed causing inconsistency on the layer state. + + +v0.9.2-alpha1 +------ +Release date: December 17, 2018
+ +* [New] Added support for scene layers. +* [New] Added support for view's columns importing in DatabaseImportHelper. +* [New] Added the ability to load view columns from database model file in DatabaseModel::createView. +* [New] Added a tab "Columns" in ReferenceWidget where the user will be able to insert columns to be used as view columns. +* [New] Added support for pagination of tables and views columns pagination. +* [New] Added a pagination toggler action on context menu at ModelWidget. +* [New] Added a fix step on CLI to remove the deprecated attribute hide-ext-attribs from tables and views xml code. +* [New] Added a configuration option to control attributes per pages in tables and views. +* [New] Added support for save collapsing states and current attributes pages to the database model file. +* [New] Added constants to reference child objects of TableObjectView. +* [New] Added the class TextPolygonItem which can be used to draw a text over a background polygon. +* [New] Added support for OLD/NEW tables aliases on triggers. +* [New] Added a hint text on RelationshipWidget to document the correct usage of default partitions. +* [New] Added support for partition attaching/detaching detection in diff process. +* [New] Added auxiliary methods in Table class in order to add/remove and retrieve partition tables. +* [New] Added support for importing partitioned/partition tables on DatabaseImportHelper. +* [New] Added a missing validation in Relationship to avoid creating other types of relationships involving partitioned or partition tables. +* [New] Added support for specify partition bounding expression on partitioning relationships. +* [New] Added support for resize grid cells to fit contents on ObjectsTableWidget. +* [New] Added a tab "Partition keys" that will handle partitioning configuration on TableWidget. +* [New] Added a method in ObjectsTableWidget to hide some horizontal header sections. +* [New] Added some validations when creating partitioning relationships. +* [New] Added support for hide columns on data manipulation dialog. +* [New] Added a transient attribute to objects DatabaseModel, Table and View in order to give a hint on the maximum count of objects held. This attribute is used to preallocate the vectors which store the children objects in order to avoid excessive memory allocation/deallocation due to vector resizing. +* [New] Added a column labeled "Alias" on all objects tables in TableWidget so the aliases of children can be displayed. +* [New] Added support for adding tabs via shortcut or corner button in the SQL Execution panel. +* [Change] Minor adjustments on MainWindow to make the overview widget to update its contents whenever the active layers change on the current model. +* [Change] Minor adjusment in ObjectsScene::addItem to make the item (in)visible according to the visibility of its related layer. +* [Change] Minor fix in AttributesTogglerItem in order to consider the parent's opacity during painting. +* [Change] Minor fixes in OperationList in order to force views to be updated correctly when operating over a table which is referenced by those objects. +* [Change] Minor adjustments on SchemaView and BaseTableView (and its children classes) to update the geometry when they switch from invisble to visible state. +* [Change] Changed views in such way so they can use the struct SimpleColumn to represent their deduced columns. +* [Change] Improved the update of views when referenced columns and tables change their structure. +* [Change] Improved database model loading times by avoiding the rendering of tables while the children objects (indexes, trigger, rules, etc) are being added. +* [Change] Removed the several operators ~ overloading that statically cast enums to their underlying type and created a template function called enum_cast in C++14 syntax. +* [Change] The zoom in/out level is now sensible on how much the user rolls the mouse wheel. +* [Change] Move the default implementation of configureObjectShadow and configureObjectSelection from BaseObjectView to BaseTableView. +* [Change] Disabling configureObjectSelection and configureObjectShadow on TableObjectView and RelationshipView. +* [Change] Minor adjustment on protected icon position on TableTitleView and TextboxView. +* [Change] Minor performance adjustments in ModelWidget. +* [Change] Minor improvement in TextboxView to use only a TextPolygonItem to hold text and the object's rectangle instead of a box and a text items. +* [Change] Replaced the sql_info_txt and sql_info_box items by a single instance of TextPolygonItem to denote SQL disabled status. +* [Change] Replace the tag_body and tag_name elements on BaseTableView by the tag_item which is a instance of TextPolygonItem. +* [Change] Improved the TableObjectView to avoid adding extra scene items. +* [Change] Improved the TableTitleView to avoid adding children items. A custom paint() method now draws them. +* [Change] Removing unused fr_FR UI translations. +* [Change] Minor update on known issues sections at README.md. +* [Change] Renamed the namespace ParsersAttributes to Attributes and its attributes has been refactored. +* [Change] Refactored all static const attributes of the classes present in pgsqltypes.h. +* [Change] Renamed PgModelerNS to PgModelerNs. +* [Change] Renamed PgModelerUiNs to PgModelerUiNs. +* [Change] Renamed XMLParser to XmlParser. +* [Change] Removing uneeded temporary QString instance created from Exception::getErroMessage call before throwing exceptions. +* [Change] Refactored static const attributes of BaseObject. +* [Change] Refactored the items in the enum ObjectType by removing the prefix 'OBJ'. +* [Change] The enums ErrorType and ObjectType were transformed into scoped enums. Also the ErrorType enum was renamed to ErrorCode. +* [Change] Code refactoring done in order to make it more close to C++14 in order to take advantage of new features introduced by that standard. +* [Change] Removed unused labels and fixed warning frame on ModelWidget. +* [Change] Minor improvements on table's attributes displaying on DatabaseExplorerWidget. +* [Change] Improved the diff process in such way to avoid generating unnecessary/noise commands related to changing types of columns to integer and setting nextval() call as default value. +* [Change] Partition tables are now displayed in the "Tables" tab at TableWidget. +* [Change] Removed the cached catalog query test feature from Catalog. +* [Change] Fine tuning on the validation of the entities used in the partitioning relationship creation. +* [Change] Forcing the partitioning relationship to be invalidated when the reference table (partitioned) partitioning type is set to null (no partitioning). +* [Change] Move the FK settings, copy options and name patterns group boxes to a dedicated tab on RelationshipWidget. +* [Change] Improved the models destruction when closing the application. +* [Change] Improved the Index/Exclude/ParitionKey elements handling by creating a generic form/grid that handles these kinds of objects (ElementsTableWidget). +* [Change] Modified the RelationshipWidget in order to handle partitioning relationships. +* [Change] Modified RelationshipConfigWidget in order to write name partterns for partitioning relationships. +* [Change] Improved the column copying and validation on class Relationship to include partitioning relationship logics. +* [Change] Improved the reverse engineering performance by avoiding update relationships as they are being imported. +* [Change] Improved the object duplication feature in ModelWidget. +* [Change] When the model is loaded it is copied to the temporary models storage as a first version of the temporary dbm file. +* [Change] Simplified the temporary models saving process by removing the thread that was controlling it. Actually the thread was unnacessary because the process was being executed in the main thread no matter if there was another thread to control the saving. +* [Change] Minor adjustment on the hint text resizing. +* [Change] Increasing to 5 minutes the period in which the temporary model saving will be executed. +* [Change] pgModeler will now use the official docs url in the help buttons. +* [Fix] Fixed a minor bug that was preventing the copy action to be enabled in DataManipulationForm. +* [Fix] Fixed some sample models to remove deprecated attributes. +* [Fix] Fixed a crash while renaming view's children objects. +* [Fix] Fixed the rendering of views which contain only a single reference that is the whole object's defintion. +* [Fix] Fixed the column name deduction for recursive views. +* [Fix] Fixed a bug that was causing crashes while configure new constraints on tables. +* [Fix] Fixed the view's resizing. +* [Fix] Fixed a regression in schema's rectangle selection. +* [Fix] Fixed the StyledTextboxView bounding rectangle. +* [Fix] Fixed an artifact when user switched on and off the compact view. +* [Fix] Fixed the Linux deploy script. +* [Fix] Fixed the macOs deploy script. +* [Fix] Fixed some compilation problems on macOs due to the usage of C++14. +* [Fix] Fixed some compilation problems on Windows due to the usage of C++14. +* [Fix] Fixed a bug in DatabaseModel::destroyObjects that could lead to segfault when the destroyed model had permissions on it. +* [Fix] Fixed a bug when importing columns which data types is some user defined type in form of array, e.g., custom_type[]. +* [Fix] Fixed a bug in SchemaParser that was causing only the first %set line in a if block to be parsed no matter that there were others %set below the same block. +* [Fix] Fixed the tooltip of some graphical objects by adding their comments and aliases. +* [Fix] Fixed the catalog query for tables to select partitioned tables correctly. +* [Fix] Fixed the catalog query for types to avoid selecting partitioned tables as being data types. +* [Fix] Fixed a bug that was causing special primary key configured on a relationship to make the original primary key of the table to disappear after disconnect the relationship. Now pgModeler stores in memory the original PK prior the connection of relationship and creation of the special PK. When disconnected the relationship, the original primary key is restored on its parent table. +* [Fix] Fixed the creation of elements (index, exclude, patition key) on DatabaseModel. +* [Fix] Fixed the class Relationship to reuse compatible columns when handling partitioning relationships. +* [Fix] Fixed the diff process in such way to create new columns with their respective COMMENT ON statement when present. +* [Fix] Fixed the detection of comment changes for columns on diff process. +* [Fix] Fixed the order of recent models saved on the file pgmodeler.conf. +* [Fix] Fixed a bug when creating a view reference as the whole view definition. +* [Fix] Minor tooltip fix on DatabaseExplorerWidget. +* [Fix] Making pgModeler honor the columns arrangement in primary keys. +* [Fix] Fixed a bug that was causing FK relationship deletion to crash the application sometimes. +* [Fix] Some fixes were done in the ModelOverviewWidget in order to support large models without exceed the screen size when configuring the size of the overall widget. +* [Fix] Fixes a bad erase in View::removeReference. +* [Fix] Fixed some bugs related to dialog size restoration in DataManipulationForm and TableWidget. + +v0.9.2-alpha +------ +Release date: August 20, 2018
+ +* [New] Added the support for cancelling SQL execution in SQLExecutionWidget. +* [New] Added support for save/restore the dialogs sizes and positions. +* [New] Added support for truncate tables in DataManipulationForm. +* [New] Added support for aliases on some graphical objects that is used in the compact view mode. +* [New] Added support for save/load object's metadata containing aliases information. +* [New] Added support for compact view of the model where graphical objects can have a more friendly name for a reduced view as well for those who don't need to see details about tables (clients of the business, for instance). +* [New] Added support for sequence options for identity columns. +* [New] Added the ability to paste CSV text from clipboard into the TableDataWidget. +* [New] Added support for bulk data edit in TableDataWidget. +* [Change] Added missing copy options on copy relationships. +* [Change] Minor adjustments on the item delegates in order draw text in the right alignment. +* [Change] Minor adjustment on buttons style in DatabaseExplorerWidget, DataManipulationForm and SQLExecutionWidget. +* [Change] Minor adjustment on OperationList::removeFromPool to avoid throw an exception when an invalid index is passed. +* [Change] Changed the behaviour of the fade in/out of relationships linked to a table by applying the effect on the other tables that are related to the selected one. +* [Change] Refactored the view editing dialog by moving the references handling form to a dedicated modal dialog. +* [Change] Improved the model loading from file by blocking signals of relationships avoiding excessive/repetive rendering of objects. The whole model is fully rendered when the file was completely loaded. +* [Change] Minor adjustment on constraints rendering at extended attributes section of tables. +* [Change] French translation update. +* [Change] Updated the other lang dictionaries with the new text brought by new releases. +* [Change] Removing icons at the top of the dialogs: DatabaseImportForm, MetaDataHandlingForm, ModelDatabaseDiffForm, ModelExportForm, ModelFixForm. +* [Change] Minor adjustments in the features of the demo version. +* [Change] Minor adjustments in the UI stylesheet. +* [Change] In DatabaseExplorerWidget the root item will come automatically selcted when browsing a database. +* [Change] Minor performance tuning when handling big models. +* [Change] Added some statistics attributes for tables on DatabaseExplorerWidget. +* [Change] Minor adjustment in NewObjectOverlayWidget by putting the tool buttons under categories. +* [Fix] Fixed a bug in ObjectFinderWidget that was forcing schemas rectangles to appear even if the flag indicating them to be visible was set to false. +* [Fix] Fixed the editing form cancel operation. Now operations done when the form was active are undone correctly. +* [Fix] Fixed a bug that was preventing to create a view containing the same name as a table but in different schema. +* [Fix] Fixed a regression that caused notices not to be shown in the output panel at SQLExecutionWidget. +* [Fix] Fixed the query catalog for policies which was causing syntax error when combining import system objects and extension objects options. +* [Fix] Fixed the disabling of some actions related to design when switching to manage view. +* [Fix] Minor fix on stylesheet in order to display the extended button on general toolbar. +* [Fix] Fix a shortcut conflict in DataManipulationform. +* [Fix] Fixed the offset of strings composing the StorageType. +* [Fix] Minor form size adjustments. +* [Fix] Minor fix in sqlexecutionwidget.ui to force the exhibition of grid headers +* [Fix] Minor fix in SQLExecutionWidget allowing the output widget to be resized to a size lower than the default one. +* [Fix] Fixed the tab order in PolicyWidget. +* [Fix] Fixed the generation of Database object source in DatabaseExplorerWidget. +* [Fix] Fixed the method BaseObjectWidget::setRequiredField to make object selector fields as required correctly. +* [Fix] Minor fix in HintTextWidget to stay on top of all widget when being displayed. +* [Fix] Fixed a bug that was not quoting extension name when needed. +* [Fix] Fixed a crash when trying to remove a fk relationship when it was created from a foreign key which references protected columns (added by relationship). +* [Fix] Fix a crash when importing CSV files into DataManipulationForm. +* [Fix] Minor typo in TableDataWidget. +* [Fix] Minor fix on schema file sql/table.sch. + +v0.9.1 +------ +Release date: May 14, 2018
+ +* [New] Added support for line selection by clicking and moving the mouse over the line numbers widget in any source code field. +* [New] The validator now checks if the model has columns referencing spatial data types and creates the postgis extension automatically when fixing the model. +* [New] Added support for RESTART IDENTITY on truncate tables in DatabaseExplorerWidget. +* [New] Added an custom option checkbox in Messagebox for general purpose usage. +* [New] Added support for diff operation in CLI. +* [New] Added support for import database from CLI. +* [New] Adding missing types regrole and regnamespace. +* [Change] Improved the copy/duplicate operation in order to copy rules, index, trigger and policies together to their parents. +* [Change] Added column names to the code completion widget used in the filter widget at DataManipulationForm. +* [Change] Improved the SQLExecutionWidget in such way that it'll display large amount of data more quickly and consuming less memory. +* [Change] Minor improvement in SQLExecutionWidget to show the amount of time took to run a query. +* [Change] Minor improvement in the text find widgets in SQL tool in order to make them closable via dedicated button. +* [Change] Improved the set tag operation in ModelWidget in order to cleanup the assigned tags to a set of objects. +* [Change] Minor improvement on DatabaseExplorerWidget to show the rls attributes labels correctly in the attributes grid. +* [Change] Refactored all the CLI options. +* [Change] Minor change in Connection::generateConnectionString in order to put the dbname param in the start of the string. +* [Change] Improved the performance of the row duplication action in DataManipulationForm. +* [Change] Minor improvement in order to update the schemas boxes when the tables have their extended attributes box toggled. +* [Change] Improved the performance of "Move to schema" operation. +* [Change] Added an busy cursor while closing a model. +* [Change] Improved the object selection in object finder. +* [Change] Changed the behaviour of select and fade buttons in ObjectFinderWidget in such way to enable the user to select/fade the objects in the listing (or not included in the results). +* [Fix] Fixed a bug when import identity columns in certain cases when the identity column was followed by another column which data type was not accepted for identity, e.g, text after smallint. +* [Fix] Fixed the check boxes disabling when dealing with identifier relationships. +* [Fix] Disabled the drag & drop for items in the side listing at ConfigurationForm. +* [Fix] Fixed the tab behavior on comment box in all editing forms of database objects. +* [Fix] Fixed the catalog query for user defined types. +* [Fix] Fixed the import of user defined types which names contains uppercase characters. +* [Fix] Minor typo fixes in CLI. +* [Fix] Fix window scaling on HiDPI/Retina screens. +* [Fix] Minor fix in Connection::getConnectionId in order to omit port when that parameter is not configured in the connection. +* [Fix] Fixed a bug in ModelExportHelper that was failing to remane the database when the command appeared. +* [Fix] Fixed a bug in CollationWidget that was referencing the collation attributes LC_??? using the wrong constant. +* [Fix] Fixed the behaviour of the message box that warns about the need of validate the model prior to export, save or diff. Now rejecting the dialog (i.e. closing it) will be considered that the user wants to proceed with the pending operation even with an invalid model. +* [Fix] Fixed the import of comments for constraints,triggers, index and rules. +* [Fix] The value input in BulkDataEditWidget will be focused as soon as the widget appears. +* [Fix] Fixed a bug in the aggregate import process. +* [Fix] Minor fix in DataManipulationForm to avoid the generation of a where clause when the filter is filled only with spaces. +* [Fix] Minor fix in the magnfier tool to use the same render hints as the canvas viewport. +* [Fix] Fixed a bug in the diff process that was trying to recreate the whole database when the "Force recreation" option was set. +* [Fix] Fixed a bug when showing the source of tables in DatabaseExplorerWidget when these objects have permissions assigned. +* [Fix] Adjusting tables position when the parent schema is moved and the alignment to grid is enabled. +* [Fix] Minor fix in the CLI menu. +* [Fix] Fixed the saving process for large models by stopping the threads related to temp models saving while the model file is being written. + v0.9.1-beta1 ------ Release date: April 6, 2018
@@ -8,21 +1718,21 @@ v0.9.1-beta1 * [New] Added the ability to create multiples one-to-many and many-to-many relatationships between the same pair of tables. * [New] Added the ability to use more special ascii chars in the middle of object names. * [New] Added missing SQL keywords into sql-highlight.conf -* [New] Added support to multi line comments in UI. +* [New] Added support for multi line comments in UI. * [New] Added code snippets for CREATE and ALTER policy. -* [New] Added full support to row level security (RLS), including export, import and diff of this kind of object. +* [New] Added full support for row level security (RLS), including export, import and diff of this kind of object. * [New] Added the method DatabaseExplorerWidget::formatPolicyAttribs in order to display some attributes values correctly. -* [New] Added support to bulk data editing in DataManipulationForm. +* [New] Added support for bulk data editing in DataManipulationForm. * [New] Added an option to diff process to force the generation of DROP commands for columns and constraints even if the missing objects need to be preserved. This is useful to work with partial models and the user need to remove columns/constraints and preserve the rest of objects. * [New] Added the ability to generate diff code to Enable/Force RLS attribute of tables. -* [New] Added support to RLS on tables. -* [New] Added the support to detect identity columns in diff. -* [New] Added support to identity columns (PostgreSQL 10). -* [New] Added the support to BYPASSRLS option on roles. -* [New] Added support to IS_TEMPLATE and ALLOW_CONNECTIONS options in database object. +* [New] Added support for RLS on tables. +* [New] Added the support for detect identity columns in diff. +* [New] Added support for identity columns (PostgreSQL 10). +* [New] Added the support for BYPASSRLS option on roles. +* [New] Added support for IS_TEMPLATE and ALLOW_CONNECTIONS options in database object. * [New] Added the procedures to fix old style domains in CLI. -* [New] Added support to multiple check constraint in domains. -* [New] Added support to sort items alphabetically (ascending) or by oid in DatabaseExplorerWidget. +* [New] Added support for multiple check constraint in domains. +* [New] Added support for sort items alphabetically (ascending) or by oid in DatabaseExplorerWidget. * [Change] Changed the input mode of the password field in ConnectionsConfigWidget in order to hide the passwords in the form. NOTE: the passwords are still in plain text in the config file. * [Change] Moved extensions from schema level to database level in order to reproduce better the PostgreSQL's behavior. * [Change] The filter widget is now toggled in DatabaseExplorerWidget via filter menu. @@ -57,7 +1767,7 @@ v0.9.1-beta ------ Release date: January 26, 2018
-* [New] Added support to GROUP BY/HAVING clauses in Views by adding a new kind of reference. Proper changes done in ViewWidget to allow configuring those clauses. +* [New] Added support for GROUP BY/HAVING clauses in Views by adding a new kind of reference. Proper changes done in ViewWidget to allow configuring those clauses. * [New] Added the method Catalog::isSystemObject(oid) which indicates if the provided OID is related to a system object. * [Change] Minor adjustment in the copy/paste operation to generate suffix in the pasted objects only when there're conflics. * [Change] Removed the port range limitation in connection configuration dialog. @@ -80,7 +1790,7 @@ v0.9.1-alpha1 * [New] Improved the data manipulation dialog in such way that when dealing with deletes in tables without PK, tuples with NULL values can be correctly considered. * [New] Improved the validations on ResultSet class. * [New] Added a method to indicate if a column value is null in ResultSet. -* [New] Added support to fade in/out objects in object finder in order to highlight the graphical objects retrieved from the search. +* [New] Added support for fade in/out objects in object finder in order to highlight the graphical objects retrieved from the search. * [New] Added an attribute in pgmodeler.conf to store the current status of the "Fade in" button in object finder widget. * [Change] Minor improvement in the diff generated metadata. * [Change] Increased the maximum allowed amount of lines in command history. @@ -93,14 +1803,14 @@ v0.9.1-alpha ------ Release date: October 20, 2017
-* [New] Added support to crow's foot notation. +* [New] Added support for crow's foot notation. * [New] Added the crow's foot notation switch in RelationshipConfigWidget. * [New] Added the grid arrangement in the arrangment menu at MainWindow. * [New] Added the schema arrangement (scattered). * [New] Added an action to toggle schemas rectangle on ModelWidget. * [New] CLI now loads the relationship and general settings to reflect relationship styles in export modes. -* [New] Added support to connect relatinship on tables' edges when using classical notation. -* [New] Added support to apostrophes in the middle of object's name. +* [New] Added support for connect relatinship on tables' edges when using classical notation. +* [New] Added support for apostrophes in the middle of object's name. * [Change] Removed the controls related to arragement in DatabaseImportForm. * [Change] Minor adjustments in tables' spacing in auto arrangement process. * [Change] Minor improvement on SQLExecutionWidget and DataManipulationForm in order to make possible to paste csv buffer from SQLExecutionWidget to DataManipulationForm. @@ -139,8 +1849,8 @@ v0.9.0 * [New] Created the method CsvLoadWidget::loadCsvFromBuffer to make the code that extract csv document from string buffer reusable by other classes. * [New] Added a new sample model donated by the maintainers of 3D City DB project. * [New] Added the language "internal" to the set of system languages available when creating a new model. -* [New] Added support to override the default language settings via GeneralConfigWidget. -* [New] Added support to toggle curved relationship lines in GeneralConfigWidget. +* [New] Added support for override the default language settings via GeneralConfigWidget. +* [New] Added support for toggle curved relationship lines in GeneralConfigWidget. * [Change] Improved the MetadataHandlingForm enabling user to only extract metada to a backup file. * [Change] Small update on sample models. * [Change] Minor adjustments in the graphical points when relationships are selected. @@ -175,11 +1885,11 @@ v0.9.0-beta2 * [New] Added a widget that shows some info about the canvas and the selected objects at the bottom of main window in design view. * [New] Enabled the usage of snippets in other portions of the software like GenericSQLWidget, FunctionWidget, ViewWidget, CustomSQLWidget. * [New] Added the ability to quickly jump to the tables related to a relationship. -* [New] Added support to select all objects in the canvas by type (table, view, textbox, schema, relationship). -* [New] Added support to bulk relationship points removal. +* [New] Added support for select all objects in the canvas by type (table, view, textbox, schema, relationship). +* [New] Added support for bulk relationship points removal. * [New] Added a magnifier tool so the user can visualize objects when the zoom is too small. This tool allows the user to click to select or activate the context menu over the objects. -* [New] Added support to generic sql objects that serve as an improved way to use custom SQL. -* [New] Added support to handle metadata related to generic sql objects. +* [New] Added support for generic sql objects that serve as an improved way to use custom SQL. +* [New] Added support for handle metadata related to generic sql objects. * [New] Added the first object auto-arrange algorithm. * [Change] pgModeler will now accept (connect) to a PostgreSQL server even if the version of the server is not supported falling back to the most recent supported. * [Change] Minor improvements on DatabaseImportForm, ModelExportForm, ModelDatabaseDiffForm and MetadataHandlingForm to toggle uniformRowsHeight of the output tree at the start and the end of each process to avoid slowdowns and allow the items to be resized correctly when expanded. @@ -207,7 +1917,7 @@ v0.9.0-beta1 * [New] Added the ability to standalone dialogs like import, diff, export and others to be resized according to the screen dpi and resolution. * [New] Added an experimental routine that will resize windows according to the current screen resolution and font dpi. -* [New] Added support to browse referrer and referenced in DataManipulationForm. +* [New] Added support for browse referrer and referenced in DataManipulationForm. * [New] Added an item under table items that stores the referrer tables in the DatabaseExplorerWidget. * [New] Added the method BaseObjectView::getScreenDpiFactor to help resize scene objects according to the screen dpi/resolution. * [Change] Minor adjustment on readonly items regarding to referenced and referrer tables in DatabaseExplorerWidget. @@ -228,8 +1938,8 @@ v0.9.0-beta ------ Release date: April 4, 2017
-* [New] Added support to indexes in Views. -* [New] Added the support to edit/load the source code in NumberedTextEditor in external application. +* [New] Added support for indexes in Views. +* [New] Added the support for edit/load the source code in NumberedTextEditor in external application. * [New] Added the ability to save/load metadata related to fade out status and extended attributes display status. * [New] Added the ability toggle the extended attributes area in tables and views. The toggle status is persisted in the model file and restores during loading * [New] Added constraints to the extended attributes section in the tables at canvas area in order to improve the quick access to these objects. @@ -237,7 +1947,7 @@ v0.9.0-beta * [New] Fade status is now persisted in the dbm file and restored during loading. * [New] Added the ability to control zoom factor from overview widget. * [New] Added a shortcut for "Duplicate" action in design view. -* [New] Added support to (back)slash char in object's names. +* [New] Added support for (back)slash char in object's names. * [New] Enabled the usage of NewObjectOverlayWidget for views. * [Change] Changed the default characters used to escape values in DataManipulationForm and TableDataWidget from {} to // due to problems with json data. * [Change] Improved the file manipulation in SQLExecutionWidget. Added option to save the commands to the current file or in another file (save as). @@ -247,7 +1957,7 @@ v0.9.0-beta * [Change] Improved the diff between the complete database and a partial model representing it. * [Fix] Minor fix in AppearanceConfigWidget in order to set the font color correctly. * [Fix] Minor fix in the default file objects-style.conf -* [Fix] Added the missing support to drop event triggers from database model. +* [Fix] Added the missing support for drop event triggers from database model. * [Fix] Fixed the drop cast command generation. * [Fix] Minor fix in windows deploy script to use newer PostgreSQL. * [Fix] Minor fix in template connections.conf file. @@ -264,21 +1974,21 @@ v0.9.0-alpha1 ------ Release date: February 07, 2017
-* [New] Added support to object moving via arrow keys in canvas area. -* [New] Added support to easily create primary keys just by checking the desired columns in table's editing form. -* [New] Added support to use middle button to handle panning mode. +* [New] Added support for object moving via arrow keys in canvas area. +* [New] Added support for easily create primary keys just by checking the desired columns in table's editing form. +* [New] Added support for use middle button to handle panning mode. * [New] Added a more user friendly message at startup whenever a missing or corrupted configuration file is detected. The user is now presented to an option to restore default settings for the problematic file. * [New] Now any default file restored in ConfigurationForm has a backup saved into the directory 'backups' inside the configuration storage. -* [New] Added support to hide the database explorer widget in SQL tool via splitter handler. +* [New] Added support for hide the database explorer widget in SQL tool via splitter handler. * [New] Added a method to disable the custom context menu of the class NumberedTextEditor. -* [New] Added support to object fading in ModelWidget. -* [New] Added the support to persist the object opacity factor in config file. +* [New] Added support for object fading in ModelWidget. +* [New] Added the support for persist the object opacity factor in config file. * [New] Added the method PgModelerUiNS::getIconPath() in order to retrieve icons from resource. -* [New] Added support to column, constraint, trigger, rule and index duplication in TableWidget. -* [New] Added support to item duplication in ObjectTableWidget. +* [New] Added support for column, constraint, trigger, rule and index duplication in TableWidget. +* [New] Added support for item duplication in ObjectTableWidget. * [New] Added a loading cursor when the user opens the DataManipulationForm. * [New] The database explorer now creates the root item in the tree as the server itself which contains data related to this latter. -* [New] Added the support to parenthesis in the middle of objects' names. +* [New] Added the support for parenthesis in the middle of objects' names. * [Change] Improvements done in the SQL history at SQL execution widget. Now the command history is saved into a specific file and restored when the application starts. * [Change] Minor improvement in DataManipulationForm to show a wait cursor while filtering results. * [Change] Minor improvements in GeneralConfigWidget. Added an readonly input that exposes the path to the current user's configuration storage. @@ -344,7 +2054,7 @@ v0.8.2 * [New] Created the PlainTextItemDelegate replacing the ReadOnlyItemDelegate where needed. * [New] Added the ability to the table to create insert commands from the initial data buffer. -* [New] Added the support to interpret initial-data tag in DatabaseModel::createTable. +* [New] Added the support for interpret initial-data tag in DatabaseModel::createTable. * [New] Create the attribute initial-data for Table in order to store the initial set of values in a CSV-like buffer. * [New] Created the form to handle table's initial data. * [New] Added the ability to duplicate rows in DataManipulationForm. @@ -352,12 +2062,12 @@ v0.8.2 * [New] Added the ability to clear and copy text from history to the sql command input field using middle mouse button in SQL tool. * [New] Added the ability to set the default connection for operations import, export, diff and validation in ConnectionsConfigWidget. * [New] Added the usage of default connections in ModelValidationWidget. -* [New] Added support to save/load default connections in the ConnectionsConfigWidget. +* [New] Added support for save/load default connections in the ConnectionsConfigWidget. * [New] Added attributes to the Connection class in order to control wheter the connection is the default for export, import, diff or validation operations. * [New] Added the ability to save the current grid options to the pgmodeler.conf file. * [New] Added a reference the svg library to the deployment scripts. -* [New] Added support to export model to SVG file in UI and CLI. -* [New] Added the support to change case and identation of the selected text in NumberedTextEditor using context menu or shortcuts. +* [New] Added support for export model to SVG file in UI and CLI. +* [New] Added the support for change case and identation of the selected text in NumberedTextEditor using context menu or shortcuts. * [New] Added a method PgModelerUiNS::createOutputListItem which created list items with an icon and text. * [New] Connections now can have a timeout between command executions. When this timeout exceeds the next command is not executed. This is a workaround to avoid the crash of the program due to connections being (unexpectedly or not) closed by the server. * [New] Added the ability to show connections notice/warning in SQL tool. @@ -419,7 +2129,7 @@ v0.8.2-beta1 * [New] Created a signal BaseObjectWidget::s_closeRequested to tell the parent form close after successfuly edit an object. * [New] Created template methods in RelationshipWidget and ViewWidget to handle child object manipulation. * [New] Created a template method TableWidget::openEditingForm to handle the editing form for children objects. -* [New] Added support to placeholder objects when moving graphical objects improving performance mainly when moving tables and relationships avoiding excessive update operations. +* [New] Added support for placeholder objects when moving graphical objects improving performance mainly when moving tables and relationships avoiding excessive update operations. * [New] Added an option to protect schema's children when protecting the schema itself. * [New] Added the abitily to diff partial models without drop the not imported ones from the original database. * [Change] CentralWidget renamed to WelcomeWidget. @@ -527,8 +2237,8 @@ v0.8.2-beta Release date: January 12, 2016
* [New] Added version descriptor for PostgreSQL 9.5 enabling pgModeler to connect to it. -* [New] Added access method BRIN for indexes, operator classes and operator families as an initial support to PostgreSQL 9.5. -* [New] Added event "table_rewrite" for event triggers as an initial support to PostgreSQL 9.5. +* [New] Added access method BRIN for indexes, operator classes and operator families as an initial support for PostgreSQL 9.5. +* [New] Added event "table_rewrite" for event triggers as an initial support for PostgreSQL 9.5. * [New] Added "Diff" action to File menu. * [Change] Minor improvement in DataManipulationForm adding the shortcut of "Copy selection" button to its tooltip. * [Change] Improvements on DataManipulationForm on how pk columns are handled and used in the generated DML commands for UPDATE and DELETE. @@ -845,7 +2555,7 @@ v0.8.0 Codename: Faithful Elephant
Release date: February 28, 2015
-* [New] Added support to multiple SQL execution widget instances for the same browsed database in SQL tool. +* [New] Added support for multiple SQL execution widget instances for the same browsed database in SQL tool. * [New] Added truncate table actions on DatabaseExplorerWidget. * [Change] Minor adjustments on ModelValidationHelper. * [Change] Minor adjustments on CustomSQLWidget. @@ -886,7 +2596,7 @@ v0.8.0-beta2 * [New] Created missing getters and setters for Operation class. * [New] Added the ability to set owner, schema and tag for several objects at once through the quick actions menu. * [New] Added an option to diff process to reuse sequences if the source model has serial columns in which the generated sequence name matches a sequence's name on the imported model. -* [New] Added the support to per-user configuration. Now each user on the system will have his separated configuration folder. +* [New] Added the support for per-user configuration. Now each user on the system will have his separated configuration folder. * [New] Added a bug report form on main window to give user the chance to report a bug without use crash handler. * [New] Added action to enable/disable an object's sql from quick actions menu at ModelWidget. * [New] Created a new namespace PgModelerUiNS to store shared constants and function in libpgmodeler_ui subproject. @@ -1161,7 +2871,7 @@ v0.8.0-alpha1 * [New] Added a field on all object's editing form to expose the object's internal id. * [New] Added an option on the database import process to generate random colors for relationships. * [New] The model objects widget gained a filtering field that is capable to list objects by their name or internal id. -* [New] Added support to custom SQL for rules, indexes and triggers. +* [New] Added support for custom SQL for rules, indexes and triggers. * [New] Added two new sample models. * [Change] Changed the shortcut for "About pgModeler" to F4 key. * [Change] Minor update on shortcuts and tooltips of buttons on bottom control bar at main window. @@ -1208,7 +2918,7 @@ v0.8.0-alpha Codename: Faithful Elephant
Release date: July 21, 2014
-* [New] Added support to using global settings for relationships on the editing form of those objects. +* [New] Added support for using global settings for relationships on the editing form of those objects. * [New] A new section was created on settings dialog to manage global configurations for relationships. * [New] Enabled the movement of schema objects without the need to select their children. This operation does not applies to protected or system schemas like public, pg_catalog. * [New] Created a more elaborated central widget with some basic operations like create, load, load recent models and restore previous session. @@ -1296,11 +3006,11 @@ v0.7.2-alpha1 * [New] Introduced a "new object" overlay widget which gives user a quick access to actions that create objects. * [New] Added a step to fix indexes with old tag on command line interface. -* [New] Added support to item interaction on "object's dependencies and references" dialog. -* [New] Added support to generate temporary names for database, roles and tablespaces when running validation process. This will avoid errors if the original database and the other objects already exists on the server. +* [New] Added support for item interaction on "object's dependencies and references" dialog. +* [New] Added support for generate temporary names for database, roles and tablespaces when running validation process. This will avoid errors if the original database and the other objects already exists on the server. * [New] Updated the CLI to include the option to generate temporary object's names. * [New] Added suppport to save and restore the last position and zoom on the canvas. This behavior can be deactivated on general settings. -* [New] Added support to prepend SQL commands on object's definition. +* [New] Added support for prepend SQL commands on object's definition. * [New] Added zoom info popup that appears whenever the user changes the current zoom factor. * [Change] Renamed the methods setCheckExpression and getCheckExpression methods to setExpression and getExpression because the expression is used either for check and exclude constraints. * [Change] Renamed the attribute "condition" to "predicate" on index class. @@ -1343,7 +3053,7 @@ v0.7.1 Release date: April 15, 2014
* [New] Added option to invert panning mode and range selection triggers. -* [New] Added support to use relationship attributes as special primary keys. +* [New] Added support for use relationship attributes as special primary keys. * [Change] Improvement on unique name generation for columns and constraints when connecting relatioships. * [Change] Improvement on copy / paste operations. * [Change] Minor workaround in order to try to fix the crash due to thread conflict mainly on Windows system. @@ -1368,7 +3078,7 @@ v0.7.1-beta Release date: April 6, 2014
* [New] Created a small interface to pgmodeler-cli that enables the user to fix a broken model inside pgModeler GUI. -* [New] Added support to assign a sequence as default value of a column. The sequence will be converted to "nextval('seqname'::regclass) and the validation process will check if the sequence is correctly referenced by the table that owns the column. +* [New] Added support for assign a sequence as default value of a column. The sequence will be converted to "nextval('seqname'::regclass) and the validation process will check if the sequence is correctly referenced by the table that owns the column. * [Change] Changed the default behavior of left click on blank areas of canvas. Instead of create a range selection the user will move the viewport (panning mode). To enable range selection user must press SHIFT and click/move to draw the selection rectangle. * [Fix] Minor fix on connection class in order to accept empty passwords as well passwords that contains spaces. * [Fix] Fixed the column listing on constraint editing form after remove one or more columns. @@ -1407,10 +3117,10 @@ v0.7.0 * [New] Addded a catalog attribute "hide-postgres-db" in order to avoid listing "postgres" maintainance DB on import operations. * [New] Added options to hide system/extension objects on SQL tool improving the object listing performance. -* [New] Added support to custom compilation output directory through qmake variables BINDIR, LIBDIR and RESDIR. -* [New] Added support to deferrable unique, exclude and primary key constraints. -* [New] Added support to custom colors on tables and views through tag objects. -* [New] Added support to export models to png image page by page. +* [New] Added support for custom compilation output directory through qmake variables BINDIR, LIBDIR and RESDIR. +* [New] Added support for deferrable unique, exclude and primary key constraints. +* [New] Added support for custom colors on tables and views through tag objects. +* [New] Added support for export models to png image page by page. * [New] Canvas can now be moved using Control + Arrow keys. If the shift is pressed the movement factor is increased. * [New] Introduced the SQL tool that permits the execution of arbitrary SQL commands direclty on a server. * [New] Added methods getType, getTypeId to BaseType and getSQLTypeName to PgSQLType as an alternative to call operators ~, ! and *. @@ -1420,11 +3130,11 @@ v0.7.0 * [New] Added a build number on about dialog. This number is the compilation date in format yyyymmdd. * [New] Added support for materialized and recursive views (PostgreSQL 9.3 feature). * [New] Added pgModeler version information on generated sql scripts as well .dbm files for debugging purpose. -* [New] Added support to custom delete/update actions for relationship generated foreign keys. -* [New] Added support to move the canvas by positioning the mouse over corners. +* [New] Added support for custom delete/update actions for relationship generated foreign keys. +* [New] Added support for move the canvas by positioning the mouse over corners. * [New] Added a configuration parameter to control font style for any source code highlight field. * [New] Added additional PostGiS types: geomval, addbandarg, rastbandarg, raster, reclassarg, unionarg, TopoGeometry, getfaceedges_returntype, validatetopology_returntype. -* [Change] Added support to on-demand updates on sql tool object's tree. +* [Change] Added support for on-demand updates on sql tool object's tree. * [Change] Improved the tab navigation experience on editing forms. * [Change] Minor change on SQL tool to ommit binary data values. * [Change] Dropped the navigation through object using Alt + due to the difficulty to understand the order in which objects are highlighted. @@ -1674,7 +3384,7 @@ v0.5.2 * [New] Introduced an experimental code completion on fields that permits code input. * [New] User can create default sequences from serial columns. This feature does not apply to columns generated by relationships. * [New] Introduced a feature to break relationship lines in straight angles and to remove all user added points. -* [New] Added support to change font size on textboxes. +* [New] Added support for change font size on textboxes. * [Change] Removed the code "OIDs=FALSE" from table's SQL. * [Fix] Minor fix on Mac OSX deployment script. @@ -1709,7 +3419,7 @@ v0.5.1 * [New] pgModeler is now capable of associate dbm files to its executable being possible opening a model from file manager by clicking it (except for MacOSX, see MacOSX notes). * [New] Added support for loading models by calling pgModeler gui executable from terminal (e.g. pgmodeler model1.dbm model2.dbm) * [New] pgModeler logo redesign. -* [New] Added special primary keys support to one-to-one and one-to-many relationships. +* [New] Added special primary keys support for one-to-one and one-to-many relationships. * [New] Relationships now supports patterns to define generated objects names. The manual suffix and auto-suffix generation are deprecated. * [New] Columns/constraints generated by relationship can have position changed on parent table. * [New] Added smallserial built-in datatype. @@ -1738,16 +3448,16 @@ v0.5.0 * [New] Added an option to list available configured connections on pgmodeler-cli. * [New] pgModeler now alerts the user when he try to save an invalidated model. * [New] pgModeler now aborts app closing when the user wants to do a last saving on modified models. -* [New] Added support to hide relationship labels and table extended attributes on configuration dialog. +* [New] Added support for hide relationship labels and table extended attributes on configuration dialog. * [New] Added "Recent Models" menu. * [New] Introduced the Xml2Object plugin to help on develpment testings. -* [New] Added partial support to PostgreSQL Extensions objects. +* [New] Added partial support for PostgreSQL Extensions objects. * [New] Added JSON datatype. * [New] Added support for rules and trigger on views. * [New] Added support for user defined range types. * [New] Added support for collations on composite types (user defined). * [New] Added built-in range types. -* [New] Added support to INCLUDING/EXCLUDING options when dealing with copy relationships. +* [New] Added support for INCLUDING/EXCLUDING options when dealing with copy relationships. * [New] Added support for EXCLUDE constraint support * [New] Added NO INHERIT option to check constraints. * [New] Added REPLICATION option to roles. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..1369b8b314 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at raphael@pgmodeler.io. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.md b/README.md index 0eff748b78..7937264d48 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,27 @@ -Introduction +![pgmodeler_mainwindow](https://user-images.githubusercontent.com/2205476/213446508-9bd549b3-ee7f-476d-9249-f537c31fce04.png) + + +[![Linux build](https://github.com/pgmodeler/pgmodeler/workflows/Linux%20build/badge.svg)](https://github.com/pgmodeler/pgmodeler/actions?query=workflow%3A%22Linux+build%22) +[![Windows build](https://github.com/pgmodeler/pgmodeler/workflows/Windows%20build/badge.svg)](https://github.com/pgmodeler/pgmodeler/actions?query=workflow%3A%22Windows+build%22) +[![macOs build](https://github.com/pgmodeler/pgmodeler/workflows/macOs%20build/badge.svg)](https://github.com/pgmodeler/pgmodeler/actions?query=workflow%3A%22macOs+build%22) + +:rocket: What's pgModeler? ------------ -pgModeler - PostgreSQL Database Modeler - is an open source data modeling tool designed for PostgreSQL. No more DDL commands written by hand let pgModeler do the job for you! This software reunites the concepts of entity-relationship diagrams and the features that PostgreSQL implements as extensions of SQL standards. +An **open-source, multiplatform database modeler for PostgreSQL**. This project aims to be a reference database design tool when it comes to FOSS in the PostgreSQL ecosystem. +Its feature-rich interface allows quick data modeling and fast code deployment on a server. It also supports reverse engineering by creating a visual representation of existing databases. Besides, pgModeler can also generate SQL scripts to sync a model and a database through the process called diff. +This tool is not about modeling only, it also counts with a minimalist but functional database server administration module that allows the execution of any sort of SQL commands, and provides database browsing and data handling in a simple and intuitive UI. + +For more details about additional features, screenshots, and other useful information, please, visit the [project's official website](https://pgmodeler.io). For any feedback about the software visit the [Issues](https://github.com/pgmodeler/pgmodeler/issues) page. Additionally, follow pgModeler on [Twitter](https://twitter.com/pgmodeler) and be up-to-date with new features, fixes, and releases. -Please, let me know how the pgModeler is working on your system! Help to improve this project, give your feedback about the software or report any bug at [Issues](https://github.com/pgmodeler/pgmodeler/issues) page. Additionaly, follow the pgModeler profile on [Facebook](https://www.facebook.com/pgmodeler) or [Twitter](https://twitter.com/pgmodeler) and be up-to-date with new features, fixes and releases. +:hammer_and_wrench: Building & Installing +---------------------- + +Being a multiplatform software, the building process differs slightly on each supported OS. This way, the installation procedures are fully described in the [Installation](https://www.pgmodeler.io/support/installation) section on the project's website. -Licensing +You may want to check the [official plugin repository](https://github.com/pgmodeler/plugins) as well for information regarding extending pgModeler's features. + +:spiral_notepad: Licensing --------- 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 version 3. @@ -14,38 +30,38 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY See [LICENSE](https://github.com/pgmodeler/pgmodeler/blob/master/LICENSE) for details. -Donate to pgModeler +:heart: pgModeler needs your support! ------------------- -Much effort, coffee, chocolate, time and knowledge has been devoted to this project so that a usable and constantly improved product could be delivered to the community. If you liked pgModeler and think it deserves a contribution please donate any amount (via PayPal) at [project's official site](http://pgmodeler.com.br). +* :coin: **Financial support:** a lot of knowledge and effort is being put into this project during the last **16 years** so that a reliable and constantly improved product can be delivered to the community. pgModeler is an independent project and has no sponsorship, living exclusively from [donations](https://pgmodeler.io/#donationForm) and [pre-compiled packages purchases](http://www.pgmodeler.io/purchase). If you like pgModeler and think it deserves a financial contribution, go ahead and help it! -Developers and Reviewers wanted! --------------------------------- +* :man_technologist: **Developers:** pgModeler has reached a state where its solo developer can't handle all the modifications and new feature requests by himself anymore in a reasonable time. So if you know how to code in C++ using the Qt framework, and want to contribute to the development, let me know! I'll be grateful for any help with the project maintenance! -pgModeler grown bigger and reached a state that its lonely developer cannot handle all the modifications and new features requests. So if you know C++ and Qt framework programming and wants to contribute with coding let me know! I'll be grateful for any help to the project! +* :speaking_head: **Other contributors:** developer or not you can always help this project by spreading the word about it. Share this repository in your social networks, workplaces, family & friends. The more the people know about pgModeler the bigger will be the support for the project, thus creating a virtuous cycle. -Compiling/Installation ----------------------- +:bookmark_tabs: Changelog +---------- + +The detailed changelog can be seen on [CHANGELOG.md](https://github.com/pgmodeler/pgmodeler/blob/master/CHANGELOG.md) file. + +:card_file_box: Older Releases & Code +------------------- -For details about installation process from source code visit the [Installation](http://www.pgmodeler.com.br/support/installation) section. If you don't want to compile pgModeler there are binaries available for purchase at [official site](http://www.pgmodeler.com.br/download). +Older releases of pgModeler can be found on [Sourceforge.net](http://sourceforge.net/projects/pgmodeler). -Known Issues +:bomb: Known Issues ----------- -* The diff process still presents false-positive results due its limitations. Sometimes, there is the need to run the process twice to get the full changes. -* pgModeler does not fully supports the [quoted identifier notation](http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS). When using quoted identifiers only the following characters are accepted in the middle of names: a-z A-Z 0-9 _ . @ $ - / \ space. -* pgModeler is unusable in sandboxed Mac OS X installations. To workaround this issue you'll need to deactivate sandbox usage to run pgModeler properly. There is no planning to adapt this tool for sandbox feature in Mac OS X. -* pgModeler can't be compiled in Microsoft Visual Studio due to use of some gcc/clang extensions. -* Compiling the source using '-Wconversion' (disabled by Qt in its default) generates a lot of warnings. These warnings are harmless in 99% of times but we can't just ignore them but I don't plan to fix them in a near future (mail me for more details). -* pgModeler sometimes can crash during the export, import or validation process due to some threaded operations that, depending on size and arrange of the model, causes race conditions. -* Due to particularities on executing bundles on MacOSX the file association does not work correctly on this system. So it's not possible to open a model file by clicking it on Finder. +* Due to the usage of Qt's raster engine to draw objects, the process of handling objects on the canvas tends to get slower as lots of objects are created causing constant CPU usage. Heavy performance degradation can be noticed when dealing with models with ~500+ tables and/or relationships. There're plans to improve the speed of drawing operations, for large models, in future releases. Changing the relationship connection mode and render smoothness options may help in the performance when handling big database models. + +* The diff process still presents false-positive results due to its limitations. Sometimes, there is the need to run the process twice and/or tweaking the options to get the full changes. -Change Log ----------- +* pgModeler does not fully support the [quoted identifier notation](http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS). When using quoted identifiers only the following characters are accepted in the middle of names: a-z A-Z 0-9 _ . @ $ - / \ space. The use of non-ASCII characters in the objects' names also implies in automatic usage of quoted notation. -The detailed log of changes can be seen on [CHANGELOG.md](https://github.com/pgmodeler/pgmodeler/blob/master/CHANGELOG.md) file. +* pgModeler can't be compiled with Microsoft Visual Studio due to the use of some GCC and clang extensions. -Older Releases/Code -------------------- +* Compiling the source using '-Wconversion' (disabled by Qt in its defaults) generates a lot of warnings. These warnings are 99% harmless and there are no plans to fix them in a near future. + +* pgModeler can sometimes crash during the export, import, validation or diff processes due to some threaded operations that, depending on the size and the arrangement of the model, cause race conditions between threads. -Older releases of pgModeler can be found at [Sourceforge.net](http://sourceforge.net/projects/pgmodeler) +* Due to the particularities of executing bundles on macOS, the file association does not work correctly on this system. So it's not possible to open a model file by clicking it on Finder. diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3840d69f48..6a56e53557 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,50 +1,42 @@ -v0.9.1-beta1 +v1.1.0-alpha1 ------ - -Release date: April 6, 2018
-Changes since: v0.9.1-beta
- -Summary: finally we've reached the last beta release of the 0.9.1! This time pgModeler brings important fixes and new features requested long ago which are finally implemented in experimental stage.
- -The first new feature we have in this release is the support to multiples relationships for the same pair of tables. In previous versions, pgModeler would refuse to create a second relationship between the tables A and B. From now on, pgModeler will accept the creation of one-to-many and many-to-many relationships linking A and B more then once. For the other kinds of relationships (generalization, copy, one-to-one) the old rule is still valid: only one relationship per table pair is accepted.
- -Some missing features of PostgreSQL are present in this version too being them: row level security (RLS) and identity columns. For RLS, introduced in PostgreSQL 9.5, we have added the related options to toggle it in tables (ENABLE|FORCE RLS) as well the support to policy objects which are the main part of this new security modality. The identity columns, introduced in PostgreSQL 10, are now fully supported by pgModeler and you can make use of them from the column editing form.
- -Other new feature is the support to multiple check constraints by domains. Actually, this is more a patch than a new feature because pgModeler was unaware that domains could support more than one check constraint, so we have fixed that now.
- -Now, talking about changes, we fixed an old missinterpretation of the PostgreSQL's documentations by changing the way extensions are stored in the database model. Previously, this kind of objects were stored at schemas level but the right way to store them is at database level. So now instead of seeing extensions in the schema's subtree you'll see them in the database subtree. All validation rules, export, import and diff processes were fixed in such way to reflect the right way to treat these objects.
- -Another important change, and that one is related to an annoying behaviour of the tool, is that pgModeler will silently ignore the absence of the plugins folder and proceed with the normal startup avoiding the display of a message box regarding the missing folder and automatically disabling the plugins search mechanism.
- -In the fixes section, we've included a patch for a bug that was causing recurrent crashes on macOS when the user tried to load a second model file making almost impossible the working on two or more database models at once. Also, we've patched the reverse engineering in such way to avoid the duplication of data types related to tables, sequences and views which was causing problems in the validation process. Another fix was done in the diff process that was generating a malformed DROP command for extensions.
- -The set of changes of this release has 47 entries between new features, changes, improvements and bug fixes. Below we highlight some of them, for the complete list, please, consider reading the CHANGELOG.md.
- -* [New] Added the ability to create multiples one-to-many and many-to-many relatationships between the same pair of tables. -* [New] Added the ability to use more special ascii chars in the middle of object names. -* [New] Added support to multi line comments in UI. -* [New] Added full support to row level security (RLS), including export, import and diff of this kind of object. -* [New] Added support to bulk data editing in DataManipulationForm. -* [New] Added an option to diff process to force the generation of DROP commands for columns and constraints even if the missing objects need to be preserved. This is useful to work with partial models and the user need to remove columns/constraints and preserve the rest of objects. -* [New] Added support to identity columns (PostgreSQL 10). -* [New] Added the support to BYPASSRLS option on roles. -* [New] Added support to IS_TEMPLATE and ALLOW_CONNECTIONS options in database object. -* [New] Added the procedures to fix old style domains in CLI. -* [New] Added support to multiple check constraint in domains. -* [New] Added support to sort items alphabetically (ascending) or by oid in DatabaseExplorerWidget. -* [Change] Changed the input mode of the password field in ConnectionsConfigWidget in order to hide the passwords in the form. NOTE: the passwords are still in plain text in the config file. -* [Change] Moved extensions from schema level to database level in order to reproduce better the PostgreSQL's behavior. -* [Change] In GeneralConfigWidget when restoring default settings the default settings for syntax highlight are restored as well. -* [Change] pgModeler will not try to create the plugins path anymore. This will avoid constant error messages during startup. Now, it'll silently ignore the absence of that folder and skip the plugin loading. -* [Change] Improved the source editing in external application. The use is informed about the app running state and the contents for the source editor field are locked until the user closes the external app. -* [Fix] Fixed the query catalog for built-in types to include the types related to domains. -* [Fix] Fixed the extension creation, allowing only one instance of the named extension per database no matter the schema used to allocate its children objects. -* [Fix] Fixed a bug when dropping Functions in DatabaseExplorerWidget. -* [Fix] Fixed a bug that was causing the disabling of connections for database models created prior to 0.9.1-beta1. -* [Fix] Fixed a bug on import process that was wrongly creating types derivated from tables/sequence/views causing duplication problems during validation. -* [Fix] Fixed a crash on macOs when opening a second model. -* [Fix] Fixed an issue in diff process that was generating a malformed DROP command for extensions. -* [Fix] Fixed the diff for domains which contain multiple check constraints. -* [Fix] Fixed a bug that was not selecting the correct spatial type in the widget. -* [Fix] Fixed a conflict of shortcuts in DatabaseExplorerWidget. Now F5 updates a leaf/subtree and Alt+F5 performs quick refresh of the tree. -* [Fix] Fixed a problem with sqlexecutionwidget.ui that is not building properly in Qt 5.10. +Release date: September 29, 2023
+Changes since: v1.1.0-alpha
+ +Attention: Some configuration files were changed in pgModeler 1.1.0-alpha1 causing a break in backward compatibility with pgModeler 1.0.x settings. This way, at the first start of the newer version, pgModeler will try to migrate the older settings to the newer ones automatically!

+ +Here we are, after working for 4 months, bringing you the last alpha release of pgModeler 1.1.0. This version was mainly focused on improving performance on several parts of the tool. So I put a huge effort into refactoring lots of code to reach an amazing (almost unbelievable) result. Let's see below: + +**Improved model loading, objects' searching, and validation speeds:** One of the most annoying things on pgModeler for me was the speed of the operations like objects' search, model validation, and, mainly, database model file loading. During the development of this version, I decided to face the challenge of improving these three operations, so I delved into the internals of the tool looking for the major bottlenecks. After selecting the problematic ones, I took the path of rewriting some mechanics instead of trying to fix them. The two main bottlenecks that degraded the speed of the mentioned operations were the objects' name validation/formatting as well as the retrieval of objects' dependencies and references. Those seemed simple operations that I even could imagine that they were making pgModeler struggle to handle big models. For the objects' name formatting and validation, I decided to create an internal name cache to avoid calling those procedures repeatedly. A simple solution that brought a surprisingly good result. For the objects' dependencies and references handling, I completely ditched the methods written for that purpose and created something infinitely simpler. Instead of calling every time a procedure that runs countless loops and recursive calls, I just made the objects store internally which other objects are their references and dependencies. Those changes made models that were loading/validating in several minutes to be processed in a few seconds. I still have some other bottlenecks to solve, but those two already removed, gave pgModeler an amazing performance.
+ +**Several other improvements:** general improvements were made all over the tool and some of them are described below.
+* Added support for inksaver color theme which uses only black and white colors for models that are used for printing.
+* Added support for using object comments as aliases in database import.
+* pgModeler now asks the user about closing SQL execution tabs that are not empty (with typed commands).
+* Add support for remembering decisions on the alerts regarding unsaved models/open SQL tabs.
+* Added an option in GeneralConfigWidget to reset the exit alert display status.
+* Added a basic form to inspect changelog XML code.
+* Added missing multirange types.
+* Improved the relationship point addition and selection via mouse clicks.
+* The "dot" grid mode is now the default in the appearance.conf file due to better drawing performance.
+* Improved the scene background (grid, delimiter, limits) drawing speed for big models.
+* Improving the objects' filtering in reverse engineering by introducing an "any" filter type.
+* Data manipulation form now shows a confirmation message before closing when items are pending save.
+ +**Bug fixes:** Also, as part of the constant search for the overall tool's stability and reliability, almost twenty bugs were fixed, and below we highlight some key ones:
+* Minor fix in the object finder widget to avoid disconnecting a null selection which could lead to crashes.
+* Minor fix in the database model widget to hide the new object overlay when moving a selection of objects in the design area.
+* Minor fix in the object removal routine in a model widget that was not erasing an object in case it shared the same name of other objects in the same schema.
+* Minor fix in the object addition routine to validate the layer of the object being added. If one or more layers are invalid the object will be moved to the default layer 0.
+* Minor fix in pgmodeler-cli when extracting the objects' XML code during model file structure repair in order to restore correctly the layers name/count.
+* Fixed a bug in partial reverse engineering that was not correctly importing functions in some specific conditions.
+* Fixed a bug in partial reverse engineering that was not importing some objects' dependencies correctly.
+* Fixed a bug in the appearance configuration widget that was not updating the example model colors when changing the UI theme.
+* Fixed a crash when double-clicking the overview widget.
+* Fixed the data dictionary schema files for tables and views.
+* Fixed a bug in the database model that was causing FK relationships of a hidden layer to be displayed after loading the model.
+* Fixed a bug in the scene move action that was causing the grid to not be displayed after a panning/wheel move.
+ +**SQL session plugin:** This version introduces the SQL session plugin, available in the paid version of the tool, which implements simple routines to save the current opened SQL command execution sessions in a specific configuration file which can be restored in the next pgModeler execution by clicking the action "Restore SQL session", close to the connections combo box, in the Manage view.
+ +Finally, for more detailed information about this release's changelog, please, refer to the CHANGELOG.md file. diff --git a/apps/apps.pri b/apps/apps.pri new file mode 100644 index 0000000000..b7569002cd --- /dev/null +++ b/apps/apps.pri @@ -0,0 +1,24 @@ +# This file contains the main variables shared by executables subprojects + +include(../pgmodeler.pri) + +unix|windows: LIBS += $$LIBGUI_LIB \ + $$LIBCANVAS_LIB \ + $$LIBCONNECTOR_LIB \ + $$LIBCORE_LIB \ + $$LIBPARSERS_LIB \ + $$LIBUTILS_LIB + +INCLUDEPATH += $$LIBGUI_INC \ + $$LIBCANVAS_INC \ + $$LIBCONNECTOR_INC \ + $$LIBCORE_INC \ + $$LIBPARSERS_INC \ + $$LIBUTILS_INC + +DEPENDPATH += $$LIBGUI_ROOT \ + $$LIBCANVAS_ROOT \ + $$LIBCONNECTOR_ROOT \ + $$LIBCORE_ROOT \ + $$LIBPARSERS_ROOT \ + $$LIBUTILS_ROOT diff --git a/apps/pgmodeler-ch/pgmodeler-ch.pro b/apps/pgmodeler-ch/pgmodeler-ch.pro new file mode 100644 index 0000000000..25a13db14d --- /dev/null +++ b/apps/pgmodeler-ch/pgmodeler-ch.pro @@ -0,0 +1,16 @@ +include(../apps.pri) + +TEMPLATE = app +TARGET = pgmodeler-ch + +windows:RC_FILE=res/windows_ico.qrc +windows:RCC_DIR=src/ + +SOURCES += src/main.cpp \ + src/crashhandlerform.cpp + +HEADERS += src/crashhandlerform.h + +# Deployment settings +target.path = $$PRIVATEBINDIR +INSTALLS = target diff --git a/apps/pgmodeler-ch/res/windows_ico.ico b/apps/pgmodeler-ch/res/windows_ico.ico new file mode 100644 index 0000000000..9affe73043 Binary files /dev/null and b/apps/pgmodeler-ch/res/windows_ico.ico differ diff --git a/crashhandler/res/windows_ico.qrc b/apps/pgmodeler-ch/res/windows_ico.qrc similarity index 100% rename from crashhandler/res/windows_ico.qrc rename to apps/pgmodeler-ch/res/windows_ico.qrc diff --git a/apps/pgmodeler-ch/src/crashhandlerform.cpp b/apps/pgmodeler-ch/src/crashhandlerform.cpp new file mode 100644 index 0000000000..216044c931 --- /dev/null +++ b/apps/pgmodeler-ch/src/crashhandlerform.cpp @@ -0,0 +1,213 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "crashhandlerform.h" +#include "messagebox.h" +#include "guiutilsns.h" + +const QString CrashHandlerForm::AnalysisMode("-analysis-mode"); + +CrashHandlerForm::CrashHandlerForm(bool analysis_mode, QWidget *parent, Qt::WindowFlags f) : BugReportForm(parent, f) +{ + QFile input; + QString buf; + QWidget *wgt=new QWidget; + QHBoxLayout *layout=new QHBoxLayout; + + setWindowTitle(tr("pgModeler crash handler")); + setWindowIcon(QPixmap(":/images/images/crashhandler.png")); + + stack_txt=new QPlainTextEdit(this); + stack_txt->setReadOnly(true); + stack_txt->setFont(QFont("Source Code Pro")); + stack_txt->setLineWrapMode(QPlainTextEdit::NoWrap); + + layout->addWidget(stack_txt); + layout->setContentsMargins(GuiUtilsNs::LtMargin,GuiUtilsNs::LtMargin,GuiUtilsNs::LtMargin,GuiUtilsNs::LtMargin); + wgt->setLayout(layout); + + logo_lbl->setPixmap(QPixmap(":/images/images/crashhandler.png")); + report_twg->addTab(wgt, tr("Stack trace")); + + //Open for reading the stack trace file generated on the last crash + input.setFileName(GlobalAttributes::getTemporaryFilePath(GlobalAttributes::StacktraceFile)); + input.open(QFile::ReadOnly); + + if(input.isOpen()) + { + buf=input.readAll(); + input.close(); + + //Removes the stack trace file + QDir stack_file; + stack_file.remove(GlobalAttributes::getTemporaryFilePath(GlobalAttributes::StacktraceFile)); + + //Shows the stacktrace loaded on the widget + stack_txt->setPlainText(buf); + } + + //Creating an input field in order to select the input report file + input_wgt=new QWidget(this); + input_wgt->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + layout=new QHBoxLayout(input_wgt); + layout->setContentsMargins(0, 0, 0, 0); + + input_lbl=new QLabel(input_wgt); + input_lbl->setText(tr("Input:")); + layout->addWidget(input_lbl); + + input_sel = new FileSelectorWidget(this); + input_sel->setFileDialogTitle(tr("Select bug report file")); + input_sel->setFileMustExist(true); + input_sel->setAcceptMode(QFileDialog::AcceptOpen); + input_sel->setNameFilters({ tr("pgModeler bug report (*.bug)"), tr("All files (*.*)") }); + input_sel->setToolTip(tr("Load report file for analysis")); + layout->addWidget(input_sel); + + save_tb=new QToolButton(input_wgt); + save_tb->setIcon(QIcon(GuiUtilsNs::getIconPath("save"))); + save_tb->setSizePolicy(attach_tb->sizePolicy()); + save_tb->setToolButtonStyle(attach_tb->toolButtonStyle()); + save_tb->setIconSize(attach_tb->iconSize()); + save_tb->setToolTip(tr("Save the attached model file on the filesystem")); + save_tb->setEnabled(false); + attach_wgt->layout()->addWidget(save_tb); + + report_tab_grid->removeWidget(details_gb); + report_tab_grid->removeWidget(output_wgt); + report_tab_grid->removeWidget(hint_frm); + + report_tab_grid->addWidget(input_wgt); + report_tab_grid->addWidget(details_gb); + report_tab_grid->addWidget(output_wgt); + report_tab_grid->addWidget(hint_frm); + + setAnalysisMode(analysis_mode); + + connect(input_sel, &FileSelectorWidget::s_fileSelected, this, &CrashHandlerForm::loadReport); + connect(input_sel, &FileSelectorWidget::s_selectorCleared, model_txt, &QPlainTextEdit::clear); + connect(input_sel, &FileSelectorWidget::s_selectorCleared, details_txt, &QPlainTextEdit::clear); + connect(input_sel, &FileSelectorWidget::s_selectorCleared, stack_txt, &QPlainTextEdit::clear); + connect(save_tb, &QToolButton::clicked, this, &CrashHandlerForm::saveModel); + + connect(model_txt, &QPlainTextEdit::textChanged, this, [this](){ + save_tb->setEnabled(!model_txt->toPlainText().isEmpty()); + }); +} + +void CrashHandlerForm::loadReport(QString filename) +{ + QFile input; + QFileInfo fi; + char *buf=nullptr; + Messagebox msgbox; + + fi.setFile(filename); + input.setFileName(filename); + input.open(QFile::ReadOnly); + + //Raises an error if the file could not be opened + if(!input.isOpen()) + msgbox.show(Exception::getErrorMessage(ErrorCode::FileDirectoryNotAccessed).arg(filename), Messagebox::ErrorIcon); + else + { + QByteArray uncomp_buf; + QString buf_aux, str_aux; + int i, idx; + QPlainTextEdit *txt_widgets[]={ details_txt, model_txt , stack_txt}; + + //Creates a text buffer + buf=new char[fi.size()]; + + //Reads the file storing it on the buffer + input.read(buf, fi.size()); + input.close(); + + //Uncompress the buffer + uncomp_buf.append(buf, fi.size()); + uncomp_buf=qUncompress(uncomp_buf); + + delete[](buf); + buf=nullptr; + + buf_aux=QString(uncomp_buf.data()); + i=idx=0; + + //Showing the sections of the uncompressed buffer on the respective widgets + while(i < buf_aux.size() && idx <= 2) + { + if(buf_aux.at(i).toLatin1()!=CharDelimiter) + str_aux.append(buf_aux.at(i)); + else + { + txt_widgets[idx++]->setPlainText(str_aux); + str_aux.clear(); + } + i++; + } + } +} + +void CrashHandlerForm::saveModel() +{ + try + { + GuiUtilsNs::selectAndSaveFile(model_txt->toPlainText().toUtf8(), + tr("Save model"), QFileDialog::AnyFile, + { tr("Database model (*%1)").arg(GlobalAttributes::DbModelExt), + tr("All files (*.*)") }, {}, + GlobalAttributes::DbModelExt); + } + catch(Exception &e) + { + Messagebox msgbox; + msgbox.show(e); + } +} + +void CrashHandlerForm::setAnalysisMode(bool value) +{ + output_wgt->setEnabled(!value); + attach_tb->setEnabled(!value); + attach_mod_chk->setEnabled(!value); + save_tb->setVisible(value); + + create_btn->setVisible(!value); + input_wgt->setVisible(value); + + if(value) + { + title_lbl->setText(tr("pgModeler crash handler")); + msg_lbl->setText(tr("Bug report analysis mode activated.")); + } + else + { + title_lbl->setText(tr("Oh no! pgModeler just crashed!")); + msg_lbl->setText(tr("We apologize for what happened! It's clear that a nasty bug caused that. Please, fill out the form below describing your actions that somehow caused the unexpected closing. This will help us to investigate the causes and provide the proper fix for the problem.")); + } +} + +QByteArray CrashHandlerForm::generateReportBuffer() +{ + QByteArray buf=BugReportForm::generateReportBuffer(); + buf.append(stack_txt->toPlainText().toUtf8()); + buf.append(CharDelimiter); + + return buf; +} diff --git a/crashhandler/src/crashhandlerform.h b/apps/pgmodeler-ch/src/crashhandlerform.h similarity index 75% rename from crashhandler/src/crashhandlerform.h rename to apps/pgmodeler-ch/src/crashhandlerform.h index c30f913798..5a38fae268 100644 --- a/crashhandler/src/crashhandlerform.h +++ b/apps/pgmodeler-ch/src/crashhandlerform.h @@ -1,7 +1,7 @@ /* # PostgreSQL Database Modeler (pgModeler) # -# Copyright 2006-2018 - Raphael Araújo e Silva +# Copyright 2006-2023 - Raphael Araújo e Silva # # 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 @@ -17,8 +17,8 @@ */ /** -\ingroup crashhandler -\class CrashHandler +\ingroup pgmodeler-ch +\class CrashHandlerForm \brief Implements the pgModeler's crash handler enabling the generation an analysis of crash report files. */ @@ -26,7 +26,7 @@ #define CRASH_HANDLER_H #include -#include "bugreportform.h" +#include "tools/bugreportform.h" class CrashHandlerForm: public BugReportForm { private: @@ -40,32 +40,27 @@ class CrashHandlerForm: public BugReportForm { QLabel *input_lbl; - //! \brief Display the path to input report file - QLineEdit *input_edt; + FileSelectorWidget *input_sel; //! \brief Triggers the model saving to filesystem - QToolButton *save_tb, - - //! \brief Triggers the report file loading - *load_tb; - - //! \brief Load a report file showing its contents on the form - void loadReport(const QString &filename); + QToolButton *save_tb; void setAnalysisMode(bool value); //! \brief Generates a report buffer containing the issue details, model and stacktrace - QByteArray generateReportBuffer(void); + QByteArray generateReportBuffer(); public: //! \brief Analysis mode argument - const static QString ANALYSIS_MODE; + static const QString AnalysisMode; - CrashHandlerForm(bool analysis_mode=false, QWidget * parent = 0, Qt::WindowFlags f = 0); + CrashHandlerForm(bool analysis_mode=false, QWidget * parent = nullptr, Qt::WindowFlags f = Qt::Widget); private slots: - void loadReport(void); - void saveModel(void); + //! \brief Load a report file showing its contents on the form + void loadReport(QString filename); + + void saveModel(); }; #endif diff --git a/apps/pgmodeler-ch/src/main.cpp b/apps/pgmodeler-ch/src/main.cpp new file mode 100644 index 0000000000..fcec8e63f1 --- /dev/null +++ b/apps/pgmodeler-ch/src/main.cpp @@ -0,0 +1,46 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "crashhandlerform.h" +#include "application.h" +#include +#include "guiutilsns.h" + +int main(int argc, char **argv) +{ + try + { + GlobalAttributes::setCustomUiScaleFactor(); + Application app(argc,argv); + QStringList args = app.arguments(); + app.loadTranslation(QLocale::system().name()); + + CrashHandlerForm crashhandler(args.size() > 1 && args[1]==CrashHandlerForm::AnalysisMode); + GuiUtilsNs::resizeDialog(&crashhandler); + crashhandler.show(); + app.exec(); + + return 0; + } + catch(Exception &e) + { + QTextStream out(stdout); + out << e.getExceptionsText(); + return enum_t(e.getErrorCode()); + } +} diff --git a/apps/pgmodeler-cli/pgmodeler-cli.pro b/apps/pgmodeler-cli/pgmodeler-cli.pro new file mode 100644 index 0000000000..7a6f320f9a --- /dev/null +++ b/apps/pgmodeler-cli/pgmodeler-cli.pro @@ -0,0 +1,18 @@ +include(../apps.pri) + +CONFIG += console +TEMPLATE = app +TARGET = pgmodeler-cli + +windows:RC_FILE = res/windows_ico.qrc +windows: RCC_DIR = src/ +windows: DESTDIR = $$PWD + +SOURCES += src/main.cpp \ + src/pgmodelercliapp.cpp + +HEADERS += src/pgmodelercliapp.h + +# Deployment settings +target.path = $$BINDIR +INSTALLS = target diff --git a/apps/pgmodeler-cli/res/windows_ico.ico b/apps/pgmodeler-cli/res/windows_ico.ico new file mode 100644 index 0000000000..d1c0f0f2dd Binary files /dev/null and b/apps/pgmodeler-cli/res/windows_ico.ico differ diff --git a/apps/pgmodeler-cli/res/windows_ico.qrc b/apps/pgmodeler-cli/res/windows_ico.qrc new file mode 100644 index 0000000000..3eb8997455 --- /dev/null +++ b/apps/pgmodeler-cli/res/windows_ico.qrc @@ -0,0 +1 @@ + IDI_ICON1 ICON DISCARDABLE "windows_ico.ico" diff --git a/apps/pgmodeler-cli/src/main.cpp b/apps/pgmodeler-cli/src/main.cpp new file mode 100644 index 0000000000..2d8728e738 --- /dev/null +++ b/apps/pgmodeler-cli/src/main.cpp @@ -0,0 +1,60 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include +#include "pgmodelercliapp.h" + +int main(int argc, char **argv) +{ + QTextStream out(stdout); + +#ifdef DEMO_VERSION + out << Qt::endl; + out << "pgModeler " << GlobalAttributes::PgModelerVersion << QT_TR_NOOP(" command line interface.") << Qt::endl; + out << QT_TR_NOOP("PostgreSQL Database Modeler Project - pgmodeler.io") << Qt::endl; + out << QT_TR_NOOP("Copyright 2006-2022 Raphael Araújo e Silva ") << Qt::endl; + out << QT_TR_NOOP("\n** CLI disabled in demonstration version! **") << Qt::endl << Qt::endl; +#else + try + { + #ifdef Q_OS_LINUX + /* Workaround to make the CLI work on Linux systems without graphical interface. + * In that case, we just check if there's a DISPLAY env var defined. If not defined + * we force the usage of the "offscreen" plugin via QT_QPA_PLATFORM so the portions of + * the application that contains GUI elements can work properly. + * + * Details at https://github.com/pgmodeler/pgmodeler/issues/1604 */ + if(qgetenv("DISPLAY").isEmpty()) + qputenv("QT_QPA_PLATFORM", "offscreen"); + #endif + + PgModelerCliApp pgmodeler_cli(argc, argv); + pgmodeler_cli.loadTranslation(QLocale::system().name()); + + //Executes the cli + return pgmodeler_cli.exec(); + } + catch(Exception &e) + { + out << Qt::endl; + out << e.getExceptionsText(); + out << "** pgmodeler-cli aborted due to critical error(s). **" << Qt::endl << Qt::endl; + return (e.getErrorCode()==ErrorCode::Custom ? -1 : enum_t(e.getErrorCode())); + } +#endif +} diff --git a/apps/pgmodeler-cli/src/pgmodelercliapp.cpp b/apps/pgmodeler-cli/src/pgmodelercliapp.cpp new file mode 100644 index 0000000000..0d9604ec5f --- /dev/null +++ b/apps/pgmodeler-cli/src/pgmodelercliapp.cpp @@ -0,0 +1,2474 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "pgmodelercliapp.h" +#include "utilsns.h" +#include "settings/appearanceconfigwidget.h" +#include "tableview.h" +#include "graphicalview.h" +#include "tableview.h" +#include "schemaview.h" +#include "styledtextboxview.h" +#include "relationshipview.h" +#include "pgsqlversions.h" + +QTextStream PgModelerCliApp::out(stdout); + +const QRegularExpression PgModelerCliApp::PasswordRegExp=QRegularExpression("(password)(=)(.)*( )"); +const QString PgModelerCliApp::PasswordPlaceholder("password=******"); + +const QString PgModelerCliApp::AllChildren("all"); +const QString PgModelerCliApp::Input("--input"); +const QString PgModelerCliApp::Output("--output"); +const QString PgModelerCliApp::InputDb("--input-db"); +const QString PgModelerCliApp::ExportToFile("--export-to-file"); +const QString PgModelerCliApp::ExportToPng("--export-to-png"); +const QString PgModelerCliApp::ExportToSvg("--export-to-svg"); +const QString PgModelerCliApp::ExportToDbms("--export-to-dbms"); +const QString PgModelerCliApp::ExportToDict("--export-to-dict"); +const QString PgModelerCliApp::ImportDb("--import-db"); +const QString PgModelerCliApp::NoIndex("--no-index"); +const QString PgModelerCliApp::Split("--split"); +const QString PgModelerCliApp::DependenciesSql("--dependencies"); +const QString PgModelerCliApp::ChildrenSql("--children"); +const QString PgModelerCliApp::Diff("--diff"); +const QString PgModelerCliApp::DropDatabase("--drop-database"); +const QString PgModelerCliApp::DropObjects("--drop-objects"); +const QString PgModelerCliApp::PgSqlVer("--pgsql-ver"); +const QString PgModelerCliApp::Help("--help"); +const QString PgModelerCliApp::ShowGrid("--show-grid"); +const QString PgModelerCliApp::ShowDelimiters("--show-delimiters"); +const QString PgModelerCliApp::PageByPage("--page-by-page"); +const QString PgModelerCliApp::IgnoreDuplicates("--ignore-duplicates"); +const QString PgModelerCliApp::IgnoreErrorCodes("--ignore-error-codes"); +const QString PgModelerCliApp::ConnAlias("--conn-alias"); +const QString PgModelerCliApp::Host("--host"); +const QString PgModelerCliApp::Port("--port"); +const QString PgModelerCliApp::User("--user"); +const QString PgModelerCliApp::Passwd("--passwd"); +const QString PgModelerCliApp::InitialDb("--initial-db"); +const QString PgModelerCliApp::Silent("--silent"); +const QString PgModelerCliApp::ListConns("--list-conns"); +const QString PgModelerCliApp::Simulate("--simulate"); +const QString PgModelerCliApp::FixModel("--fix-model"); +const QString PgModelerCliApp::FixTries("--fix-tries"); +const QString PgModelerCliApp::ZoomFactor("--zoom"); +const QString PgModelerCliApp::UseTmpNames("--use-tmp-names"); +const QString PgModelerCliApp::DbmMimeType("--dbm-mime-type"); +const QString PgModelerCliApp::Install("install"); +const QString PgModelerCliApp::Uninstall("uninstall"); +const QString PgModelerCliApp::SystemWide("--system-wide"); +const QString PgModelerCliApp::IgnoreImportErrors("--ignore-errors"); +const QString PgModelerCliApp::ImportSystemObjs("--import-sys-objs"); +const QString PgModelerCliApp::ImportExtensionObjs("--import-ext-objs"); +const QString PgModelerCliApp::DebugMode("--debug-mode"); +const QString PgModelerCliApp::FilterObjects("--filter-objects"); +const QString PgModelerCliApp::MatchByName("--match-by-name"); +const QString PgModelerCliApp::ForceChildren("--force-children"); +const QString PgModelerCliApp::OnlyMatching("--only-matching"); +const QString PgModelerCliApp::CommentsAsAliases("--comments-as-aliases"); +const QString PgModelerCliApp::PartialDiff("--partial"); +const QString PgModelerCliApp::Force("--force"); +const QString PgModelerCliApp::StartDate("--start-date"); +const QString PgModelerCliApp::EndDate("--end-date"); +const QString PgModelerCliApp::CompareTo("--compare-to"); +const QString PgModelerCliApp::SaveDiff("--save"); +const QString PgModelerCliApp::ApplyDiff("--apply"); +const QString PgModelerCliApp::NoDiffPreview("--no-preview"); +const QString PgModelerCliApp::DropClusterObjs("--drop-cluster-objs"); +const QString PgModelerCliApp::RevokePermissions("--revoke-perms"); +const QString PgModelerCliApp::DropMissingObjs("--drop-missing"); +const QString PgModelerCliApp::ForceDropColsConstrs("--force-drop-cols"); +const QString PgModelerCliApp::RenameDb("--rename-db"); +const QString PgModelerCliApp::NoSequenceReuse("--no-sequence-reuse"); +const QString PgModelerCliApp::NoCascadeDrop("--no-cascade"); +const QString PgModelerCliApp::ForceRecreateObjs("--force-recreate-objs"); +const QString PgModelerCliApp::OnlyUnmodifiable("--only-unmodifiable"); +const QString PgModelerCliApp::CreateConfigs("--create-configs"); +const QString PgModelerCliApp::MissingOnly("--missing-only"); + +const QString PgModelerCliApp::TagExpr("<%1"); +const QString PgModelerCliApp::EndTagExpr(" PgModelerCliApp::long_opts = { + { Input, true }, { Output, true }, { InputDb, true }, + { ExportToFile, false }, { ExportToPng, false }, { ExportToSvg, false }, + { ExportToDbms, false }, { ImportDb, false }, { Diff, false }, + { DropDatabase, false }, { DropObjects, false }, { PgSqlVer, true }, + { Help, false }, { ShowGrid, false }, { ShowDelimiters, false }, + { PageByPage, false }, { IgnoreDuplicates, false }, { IgnoreErrorCodes, true }, + { ConnAlias, true }, { Host, true }, { Port, true }, + { User, true }, { Passwd, true }, { InitialDb, true }, + { ListConns, false }, { Simulate, false }, { FixModel, false }, + { FixTries, true }, { ZoomFactor, true }, { UseTmpNames, false }, + { DbmMimeType, true }, { IgnoreImportErrors, false }, { ImportSystemObjs, false }, + { ImportExtensionObjs, false }, { FilterObjects, true }, { ForceChildren, true }, + { OnlyMatching, false }, { MatchByName, false }, { DebugMode, false }, + { PartialDiff, false }, { StartDate, true }, { EndDate, true }, + { CompareTo, true }, { SaveDiff, false }, { ApplyDiff, false }, + { NoDiffPreview, false }, { DropClusterObjs, false }, { RevokePermissions, false }, + { DropMissingObjs, false }, { ForceDropColsConstrs, false }, { RenameDb, false }, + { NoSequenceReuse, false }, { NoCascadeDrop, false }, + { ForceRecreateObjs, false }, { OnlyUnmodifiable, false }, { ExportToDict, false }, + { NoIndex, false }, { Split, false }, { SystemWide, false }, + { CreateConfigs, false }, { Force, false }, { MissingOnly, false }, + { DependenciesSql, false }, { ChildrenSql, false }, { CommentsAsAliases, false } +}; + +std::map PgModelerCliApp::accepted_opts = { + {{ Attributes::Connection }, { ConnAlias, Host, Port, User, Passwd, InitialDb }}, + {{ ExportToFile }, { Input, Output, PgSqlVer, Split, DependenciesSql, ChildrenSql }}, + {{ ExportToPng }, { Input, Output, ShowGrid, ShowDelimiters, PageByPage, ZoomFactor }}, + {{ ExportToSvg }, { Input, Output, ShowGrid, ShowDelimiters }}, + {{ ExportToDict }, { Input, Output, Split, NoIndex }}, + + {{ ExportToDbms }, { Input, PgSqlVer, IgnoreDuplicates, IgnoreErrorCodes, + DropDatabase, DropObjects, Simulate, UseTmpNames }}, + + {{ ImportDb }, { InputDb, Output, IgnoreImportErrors, ImportSystemObjs, ImportExtensionObjs, + FilterObjects, OnlyMatching, MatchByName, ForceChildren, DebugMode, ConnAlias, + Host, Port, User, Passwd, InitialDb, CommentsAsAliases }}, + + {{ Diff }, { Input, PgSqlVer, IgnoreDuplicates, IgnoreErrorCodes, CompareTo, PartialDiff, Force, + StartDate, EndDate, SaveDiff, ApplyDiff, NoDiffPreview, DropClusterObjs, RevokePermissions, + DropMissingObjs, ForceDropColsConstrs, RenameDb, NoCascadeDrop, + NoSequenceReuse, ForceRecreateObjs, OnlyUnmodifiable }}, + + {{ DbmMimeType }, { SystemWide, Force }}, + {{ FixModel }, { Input, Output, FixTries }}, + {{ ListConns }, {}}, + {{ CreateConfigs }, {MissingOnly, Force}} +}; + +PgModelerCliApp::PgModelerCliApp(int argc, char **argv) : Application(argc, argv) +{ + try + { + QString op, value, orig_op; + bool accepts_val=false; + attribs_map opts; + QStringList args = arguments(); + + has_fix_log = false; + buffer_size = 0; + model=nullptr; + scene=nullptr; + xmlparser=nullptr; + zoom=1; + + export_hlp = nullptr; + import_hlp = nullptr; + diff_hlp = nullptr; + conn_conf = nullptr; + rel_conf = nullptr; + general_conf = nullptr; + + // We extract the options values only if the help option is not present + if(args.size() > 1 && !args.contains(Help) && !args.contains(short_opts[Help])) + { + for(int i=1; i < argc; i++) + { + op = orig_op = argv[i]; + + //If the retrieved option starts with - it will be treated as a command option + if(op[0]=='-') + { + value.clear(); + + if(i < argc-1 && argv[i+1][0]!='-') + { + //If the next option does not starts with '-', is considered a value + value=argv[++i]; + } + + //Raises an error if the option is not recognized + if(!isOptionRecognized(op, accepts_val)) + throw Exception(tr("Unrecognized option `%1'.").arg(orig_op), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Raises an error if the value is empty and the option accepts a value + if(accepts_val && value.isEmpty()) + throw Exception(tr("Value not specified for option `%1'.").arg(orig_op), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + else if(!accepts_val && !value.isEmpty()) + throw Exception(tr("Option `%1' does not accept values.").arg(orig_op), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* If we find a filter object parameter we append its parameter index so + * its value is not replaced by the next filter parameter found */ + if(op == FilterObjects) + opts[QString("%1%2").arg(op).arg(i)] = value; + + opts[op] = value; + } + } + } + + //Validates and executes the options + parseOptions(opts); + + if(!parsed_opts.empty()) + { + model=new DatabaseModel; + xmlparser=model->getXMLParser(); + silent_mode=(parsed_opts.count(Silent)); + + //If the export is to png or svg loads additional configurations + if(parsed_opts.count(ExportToPng) || parsed_opts.count(ExportToSvg) || parsed_opts.count(ImportDb)) + { + connect(model, &DatabaseModel::s_objectAdded, this, &PgModelerCliApp::handleObjectAddition); + connect(model, &DatabaseModel::s_objectRemoved, this, &PgModelerCliApp::handleObjectRemoval); + + //Load the appearance settings including grid and delimiter options + AppearanceConfigWidget appearance_wgt; + appearance_wgt.loadConfiguration(); + + scene=new ObjectsScene; + scene->setParent(this); + scene->setSceneRect(QRectF(0,0,2000,2000)); + } + + if(parsed_opts.count(ExportToDbms) || parsed_opts.count(ImportDb) || parsed_opts.count(Diff)) + { + configureConnection(false); + + //Replacing the initial db parameter for the input database when reverse engineering + if((parsed_opts.count(ImportDb) || parsed_opts.count(Diff)) && !parsed_opts[InputDb].isEmpty()) + connection.setConnectionParam(Connection::ParamDbName, parsed_opts[InputDb]); + } + + if(parsed_opts.count(Diff)) + { + configureConnection(true); + + if(!extra_connection.isConfigured()) + extra_connection = connection; + + extra_connection.setConnectionParam(Connection::ParamDbName, parsed_opts[CompareTo]); + } + + if(!silent_mode && export_hlp && import_hlp && diff_hlp) + { + connect(export_hlp, &ModelExportHelper::s_progressUpdated, this, &PgModelerCliApp::updateProgress); + connect(export_hlp, &ModelExportHelper::s_errorIgnored, this, &PgModelerCliApp::printIgnoredError); + connect(import_hlp, &DatabaseImportHelper::s_progressUpdated, this, &PgModelerCliApp::updateProgress); + connect(diff_hlp, &ModelsDiffHelper::s_progressUpdated, this, &PgModelerCliApp::updateProgress); + } + } + } + catch(Exception &e) + { + throw e; + } +} + +PgModelerCliApp::~PgModelerCliApp() +{ + bool show_flush_msg = model && model->getObjectCount() > 0; + + if(show_flush_msg) + printMessage(tr("Flushing used memory...")); + + if(scene) + delete scene; + + delete model; + + if(export_hlp) + delete export_hlp; + + if(import_hlp) + delete import_hlp; + + if(diff_hlp) + delete diff_hlp; + + if(conn_conf) + delete conn_conf; + + if(rel_conf) + delete rel_conf; + + if(general_conf) + delete general_conf; + + if(show_flush_msg) + printMessage(tr("Done!")); +} + +void PgModelerCliApp::printText(const QString &txt) +{ + out << txt << Qt::endl; +} + +void PgModelerCliApp::printMessage(const QString &txt) +{ + if(!silent_mode) + printText(txt); +} + +void PgModelerCliApp::configureConnection(bool extra_conn) +{ + QString chr = (extra_conn ? "1" : ""); + Connection *conn = (extra_conn ? &extra_connection : &connection); + + //Getting the connection using its alias + if(parsed_opts.count(ConnAlias + chr)) + { + if(!connections.count(parsed_opts[ConnAlias + chr])) + throw Exception(tr("Connection aliased as '%1' was not found in the configuration file.").arg(parsed_opts[ConnAlias + chr]), + ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Make a copy of the named connection + *conn = (*connections[parsed_opts[ConnAlias + chr]]); + } + else + { + conn->setConnectionParam(Connection::ParamServerFqdn, parsed_opts[Host + chr]); + conn->setConnectionParam(Connection::ParamUser, parsed_opts[User + chr]); + conn->setConnectionParam(Connection::ParamPort, parsed_opts[Port + chr]); + conn->setConnectionParam(Connection::ParamPassword, parsed_opts[Passwd + chr]); + conn->setConnectionParam(Connection::ParamDbName, parsed_opts[InitialDb + chr]); + } +} + +bool PgModelerCliApp::isOptionRecognized(QString &op, bool &accepts_val) +{ + bool found=false, append_chr = false; + + if(op.endsWith('1')) + { + op.chop(1); + append_chr = true; + } + + for(auto &itr : short_opts) + { + found=(op==itr.first || op==itr.second); + accepts_val=(found && long_opts[itr.first]); + + if(found) + { + op = itr.first; + break; + } + } + + if(append_chr) op += '1'; + return found; +} + +void PgModelerCliApp::showVersionInfo() +{ + printMessage(); + printMessage(tr("pgModeler command line interface.") ); + printMessage(tr("Version ") + GlobalAttributes::PgModelerVersion + QString(" - %1 Qt %2").arg(GlobalAttributes::PgModelerBuildNumber).arg(QT_VERSION_STR)); + printMessage(tr("PostgreSQL Database Modeler Project - pgmodeler.io") ); + printMessage(tr("Copyright 2006-%1 Raphael Araújo e Silva ").arg(QDate::currentDate().year())); + printMessage(); +} + +void PgModelerCliApp::showMenu() +{ + showVersionInfo(); + + printText(tr("Usage: pgmodeler-cli [OPTIONS]")); + printText(tr("This CLI tool provides several operations over models and databases without the need to perform them\n in the pgModeler's graphical interface. All available options are described below.")); + printText(); + + printText(tr("Operation mode options: ")); + printText(tr(" %1, %2\t\t Exports the input model to SQL script file(s).").arg(short_opts[ExportToFile]).arg(ExportToFile)); + printText(tr(" %1, %2\t\t Exports the input model to a PNG image.").arg(short_opts[ExportToPng]).arg(ExportToPng) ); + printText(tr(" %1, %2\t\t Exports the input model to a SVG file.").arg(short_opts[ExportToSvg]).arg(ExportToSvg) ); + printText(tr(" %1, %2\t\t Exports the input model to a data dictionary in HTML format.").arg(short_opts[ExportToDict]).arg(ExportToDict)); + printText(tr(" %1, %2\t\t Exports the input model directly to a PostgreSQL server.").arg(short_opts[ExportToDbms]).arg(ExportToDbms)); + printText(tr(" %1, %2\t\t Lists the available connections in file %3.").arg(short_opts[ListConns]).arg(ListConns).arg(GlobalAttributes::ConnectionsConf + GlobalAttributes::ConfigurationExt)); + printText(tr(" %1, %2\t\t Importa a database to an output file.").arg(short_opts[ImportDb]).arg(ImportDb)); + printText(tr(" %1, %2\t\t\t Compares a model and a database or two databases generating the SQL script to sync the latter in relation to the first.").arg(short_opts[Diff]).arg(Diff)); + printText(tr(" %1, %2\t\t Tries to fix the structure of the input model file to make it loadable again.").arg(short_opts[FixModel]).arg(FixModel)); + printText(tr(" %1, %2\t\t Creates the pgModeler's configuration folder and files in the user's local storage.").arg(short_opts[CreateConfigs]).arg(CreateConfigs)); +#ifndef Q_OS_MAC + printText(tr(" %1, %2 [ACTION]\t Handles the DBM file association to pgModeler binaries. The ACTION can be [%3 | %4].").arg(short_opts[DbmMimeType]).arg(DbmMimeType).arg(Install).arg(Uninstall)); +#endif + printText(tr(" %1, %2\t\t\t Shows this help menu.").arg(short_opts[Help]).arg(Help)); + printText(); + + printText(tr("General options: ")); + printText(tr(" %1, %2 [FILE]\t\t Input model file (%3). This is mandatory for export and model fix operations.").arg(short_opts[Input], Input, GlobalAttributes::DbModelExt)); + printText(tr(" %1, %2 [DBNAME]\t Input database name. This is mandatory for import operation.").arg(short_opts[InputDb]).arg(InputDb)); + printText(tr(" %1, %2 [FILE|DIRECTORY] Output file or directory. This is mandatory for fixing models or exporting to SQL, HTML, PNG, or SVG.").arg(short_opts[Output]).arg(Output)); + printText(tr(" %1, %2\t\t Force the PostgreSQL syntax to the specified version when generating SQL code. The version string must be in the form of [major].[minor], e.g., %3.").arg(short_opts[PgSqlVer]).arg(PgSqlVer).arg(PgSqlVersions::DefaulVersion)); + printText(tr(" %1, %2\t\t\t Silent execution. Only critical messages and errors are shown during the process.").arg(short_opts[Silent]).arg(Silent)); + printText(); + + printText(tr("SQL file export options: ")); + printText(tr(" %1, %2\t\t\t The SQL file is generated per object. The files will be named in such a way to reflect the correct creation order of the objects.").arg(short_opts[Split]).arg(Split)); + printText(tr(" %1, %2\t\t Includes the object's dependencies SQL code in the generated file. (Only for split mode)").arg(short_opts[DependenciesSql]).arg(DependenciesSql)); + printText(tr(" %1, %2\t\t Includes the object's children SQL code in the generated file. (Only for split mode)").arg(short_opts[ChildrenSql]).arg(ChildrenSql)); + printText(); + + printText(tr("PNG and SVG export options: ")); + printText(tr(" %1, %2\t\t Draws the grid in the exported image.").arg(short_opts[ShowGrid]).arg(ShowGrid)); + printText(tr(" %1, %2\t Draws the page delimiters in the exported image.").arg(short_opts[ShowDelimiters]).arg(ShowDelimiters)); + printText(tr(" %1, %2\t\t Each page will be exported in a separated image. (Only for PNG images)").arg(short_opts[PageByPage]).arg(PageByPage)); + printText(tr(" %1, %2 [FACTOR]\t\t Applies a zoom (in percent) before export to an image. Accepted zoom interval: %3-%4 (Only for PNG images)").arg(short_opts[ZoomFactor]).arg(ZoomFactor).arg(ModelWidget::MinimumZoom*100).arg(ModelWidget::MaximumZoom*100)); + printText(); + + printText(tr("Data dictionary export options: ")); + printText(tr(" %1, %2\t\t\t The data dictionaries are generated in separated files inside the specified output directory.").arg(short_opts[Split]).arg(Split)); + printText(tr(" %1, %2\t\t Avoids the generation of the index that is used to help navigate through the data dictionary.").arg(short_opts[NoIndex]).arg(NoIndex)); + printText(); + + printText(tr("DBMS export options: ")); + printText(tr(" %1, %2\t Ignores errors related to duplicate objects that eventually exist in the server.").arg(short_opts[IgnoreDuplicates]).arg(IgnoreDuplicates)); + printText(tr(" %1, %2 [CODES] Ignores additional errors by their codes. A comma-separated list of alphanumeric codes should be provided.").arg(short_opts[IgnoreErrorCodes]).arg(IgnoreErrorCodes)); + printText(tr(" %1, %2\t\t Drop the database before executing an export process.").arg(short_opts[DropDatabase]).arg(DropDatabase)); + printText(tr(" %1, %2\t\t Runs the DROP commands attached to objects in which SQL code is enabled.").arg(short_opts[DropObjects]).arg(DropObjects)); + printText(tr(" %1, %2\t\t Simulates an export process by executing all steps but undoing any modification in the end.").arg(short_opts[Simulate]).arg(Simulate)); + printText(tr(" %1, %2\t\t Generates temporary names for database, roles, and tablespaces when in simulation mode.").arg(short_opts[UseTmpNames]).arg(UseTmpNames)); + printText(); + + printText(tr("Connection options: ")); + printText(tr(" %1, %2 [ALIAS]\t Connection configuration alias to be used.").arg(short_opts[ConnAlias]).arg(ConnAlias)); + printText(tr(" %1, %2 [HOST]\t\t PostgreSQL host in which a task will operate.").arg(short_opts[Host]).arg(Host)); + printText(tr(" %1, %2 [PORT]\t\t PostgreSQL host listening port.").arg(short_opts[Port]).arg(Port)); + printText(tr(" %1, %2 [USER]\t\t PostgreSQL username.").arg(short_opts[User]).arg(User)); + printText(tr(" %1, %2 [PASSWORD]\t PostgreSQL user password.").arg(short_opts[Passwd]).arg(Passwd)); + printText(tr(" %1, %2 [DBNAME]\t Connection's initial database.").arg(short_opts[InitialDb]).arg(InitialDb)); + printText(); + + printText(tr("Database import options: ")); + printText(tr(" %1, %2\t\t Ignores all errors and tries to create as many as possible objects.").arg(short_opts[IgnoreImportErrors]).arg(IgnoreImportErrors)); + printText(tr(" %1, %2\t Imports built-in system objects. This option causes the model to bloat due to the importing of unneeded objects.").arg(short_opts[ImportSystemObjs]).arg(ImportSystemObjs)); + printText(tr(" %1, %2\t Imports extension objects. This option causes the model to bloat due to the importing of unneeded objects.").arg(short_opts[ImportExtensionObjs]).arg(ImportExtensionObjs)); + printText(tr(" %1, %2\t Use objects comments as aliases. This option is takes effect on objects graphically represented in the database model.").arg(short_opts[CommentsAsAliases]).arg(CommentsAsAliases)); + printText(tr(" %1, %2 [FILTER] Makes the import process retrieve only those objects matching the filter(s). The FILTER should be in the form type:pattern:mode.").arg(short_opts[FilterObjects]).arg(FilterObjects)); + printText(tr(" %1, %2\t\t Makes only objects matching the provided filter(s) to be imported. Those not matching filter(s) are discarded.").arg(short_opts[OnlyMatching]).arg(OnlyMatching)); + printText(tr(" %1, %2\t\t Makes the objects matching to be performed over their names instead of their signature ([schema].[name]).").arg(short_opts[MatchByName]).arg(MatchByName)); + printText(tr(" %1, %2 [OBJECTS] Forces the importing of children objects related to tables/views/foreign tables matched by the filter(s). The OBJECTS is a comma separated list types.").arg(short_opts[ForceChildren]).arg(ForceChildren)); + printText(tr(" %1, %2\t\t Runs the import in debug mode printing all queries executed in the server.").arg(short_opts[DebugMode]).arg(DebugMode)); + printText(); + + printText(tr("Diff options: ")); + printText(tr(" %1, %2 [DBNAME]\t The database used in the comparison. All the SQL code generated is applied to it.").arg(short_opts[CompareTo]).arg(CompareTo)); + printText(tr(" %1, %2\t\t Switches to the partial diff operation. A set of object filters should be provided using the import option %3.").arg(short_opts[PartialDiff]).arg(PartialDiff).arg(FilterObjects)); + printText(tr(" %1, %2\t\t\t Forces a full diff if the provided filters were not able to retrieve objects for a partial diff operation.").arg(short_opts[Force]).arg(Force)); + printText(tr(" %1, %2\t\t Matches all database model objects in which the modification date starts on the specified date. (Only for partial diff)").arg(short_opts[StartDate]).arg(StartDate)); + printText(tr(" %1, %2\t\t Matches all database model objects in which the modification date ends on the specified date. (Only for partial diff)").arg(short_opts[EndDate]).arg(EndDate)); + printText(tr(" %1, %2\t\t\t Saves the generated diff code to the output file.").arg(short_opts[SaveDiff]).arg(SaveDiff)); + printText(tr(" %1, %2\t\t\t Applies the generated diff code on the database server.").arg(short_opts[ApplyDiff]).arg(ApplyDiff)); + printText(tr(" %1, %2\t\t Don't preview the generated diff code before applying it to the server.").arg(short_opts[NoDiffPreview]).arg(NoDiffPreview)); + printText(tr(" %1, %2\t Drop cluster-level objects like roles and tablespaces.").arg(short_opts[DropClusterObjs]).arg(DropClusterObjs)); + printText(tr(" %1, %2\t\t Revokes permissions already set on the database. New permissions configured in the input model are still applied.").arg(short_opts[RevokePermissions]).arg(RevokePermissions)); + printText(tr(" %1, %2\t\t Drops missing objects. Generates DROP commands for objects that are present in the input model but not in the compared database.").arg(short_opts[DropMissingObjs]).arg(DropMissingObjs)); + printText(tr(" %1, %2\t Forces the drop of missing columns and constraints. Causes only columns and constraints to be dropped, other missing objects aren't removed.").arg(short_opts[ForceDropColsConstrs]).arg(ForceDropColsConstrs)); + printText(tr(" %1, %2\t\t Renames the destination database when the names of the involved databases are different.").arg(short_opts[RenameDb]).arg(RenameDb)); + printText(tr(" %1, %2\t\t Don't drop objects in cascade mode.").arg(short_opts[NoCascadeDrop]).arg(NoCascadeDrop)); + printText(tr(" %1, %2\t Don't reuse sequences on serial columns. Drop the old sequence assigned to a serial column and creates a new one.").arg(short_opts[NoSequenceReuse]).arg(NoSequenceReuse)); + printText(tr(" %1, %2\t Forces recreating the objects. Instead of an ALTER command, the DROP and CREATE commands are used to create new versions of the objects.").arg(short_opts[ForceRecreateObjs]).arg(ForceRecreateObjs)); + printText(tr(" %1, %2\t Recreates only the unmodifiable objects. These objects are the ones that can't be changed via ALTER command.").arg(short_opts[OnlyUnmodifiable]).arg(OnlyUnmodifiable)); + printText(); + + printText(tr("Model fix options: ") ); + printText(tr(" %1, %2 [NUMBER]\t Model fix tries. When reaching the maximum count the invalid objects will be discarded.").arg(short_opts[FixTries]).arg(FixTries)); + printText(); + +#ifndef Q_OS_MAC + printText(tr("File association options: ")); + printText(tr(" %1, %2\t\t The file association to DBM files will be applied on a system-wide level instead of to the current user only.").arg(short_opts[SystemWide]).arg(SystemWide)); + printText(tr(" %1, %2 \t\t\t Forces the mime type install or uninstall. ").arg(short_opts[Force]).arg(Force)); + printText(); +#endif + + printText(tr("Config files creation options: ")); + printText(tr(" %1, %2 \t\t Copies only missing configuration files to the user's local storage.").arg(short_opts[MissingOnly]).arg(MissingOnly)); + printText(tr(" %1, %2 \t\t\t Forces the recreation of all configuration files. This option implies the backup of the current settings.").arg(short_opts[Force]).arg(Force)); + printText(); + + printText(); + printText(tr("** The FILTER value in %1 option has the form type:pattern:mode. ").arg(FilterObjects)); + printText(tr(" * The section `type' is the type of object to be filtered and accepts the following values (invalid types ignored): ")); + + QStringList list; + QString child_list; + + for(auto &type : BaseObject::getChildObjectTypes(ObjectType::Table)) + { + if(type == ObjectType::Column) + continue; + + list.append(BaseObject::getSchemaName(type)); + } + + list.sort(); + child_list = list.join(", "); + + QStringList fmt_types, lines, type_list = Catalog::getFilterableObjectNames(); + int i = 0; + + type_list.prepend(Attributes::Any); + + for(auto &type : type_list) + { + fmt_types.append(type); + i++; + if(i % 8 == 0 || i == type_list.size() - 1) + { + lines.append(" > " + fmt_types.join(", ")); + fmt_types.clear(); + } + } + printText(lines.join('\n')); + + printText(); + printText(tr(" * The special type `%1' allows writing a single filter that applies to all object types.").arg(Attributes::Any)); + printText(); + printText(tr(" * The section `pattern' is the text pattern that is matched against the objects' names.")); + printText(); + printText(tr(" * The section `mode' is the way the pattern is matched. This one accepts two values: ")); + printText(tr(" > `%1' causes the pattern to be used as a wildcard string while matching objects' names.").arg(UtilsNs::FilterWildcard)); + printText(tr(" > `%1' causes the pattern to be treated as a Perl-like regular expression while matching objects' names.").arg(UtilsNs::FilterRegExp)); + printText(); + printText(tr(" * The option %1 takes effect only when used with %2 and will avoid discarding children of matched tables.").arg(ForceChildren).arg(OnlyMatching)); + printText(tr(" Other tables eventually imported which are dependencies of the matched objects will have their children discarded.")); + printText(tr(" The comma-separated list of table children objects accepts the values:")); + printText(tr(" > %1").arg(child_list) ); + printText(tr(" > Use the special keyword `%1' to force all children objects.").arg(AllChildren) ); + printText(); + printText(tr(" * NOTES: all comparisons during the filtering process are case insensitive.")); + printText(tr(" Using the filtering options may cause the importing of additional objects due to the automatic dependency resolution.")); + printText(); + printText(tr("** The diff process allows the usage of all options related to the import operation.")); + printText(tr(" It also accepts the following export operation options: `%1', `%2'").arg(IgnoreDuplicates).arg(IgnoreErrorCodes)); + printText(); + printText(tr("** The partial diff operation will always force the options %1 and %2 = %3 for more reliable results.").arg(OnlyMatching).arg(ForceChildren).arg(AllChildren)); + printText(tr(" * The options %1 and %2 accepts the ISO8601 date/time format: yyyy-MM-dd hh:mm:ss").arg(StartDate).arg(EndDate)); + printText(); + printText(tr("** When running the diff using two databases (%1 and %2) there's the option to specify two separated connections/aliases.").arg(InputDb).arg(CompareTo)); + printText(tr(" If only one connection is set then it will be used to import the input database as well to retrieve the database used in the comparison.")); + printText(tr(" A second connection can be specified by appending a 1 to any connection configuration parameter listed above.")); + printText(tr(" This causes the connection to be associated to %1 exclusively.").arg(CompareTo)); + printText(); +} + +void PgModelerCliApp::listConnections() +{ + std::map::iterator itr=connections.begin(); + + if(connections.empty()) + printText(tr("There are no connections configured.")); + else + { + unsigned id=0; + + printText(tr("Available connections (alias : connection string)")); + + while(itr != connections.end()) + { + printText("[" + QString::number(id++) + "] " + itr->first + " : " + + itr->second->getConnectionString().replace(PasswordRegExp, PasswordPlaceholder)); + itr++; + } + + printText(); + } +} + +void PgModelerCliApp::parseOptions(attribs_map &opts) +{ + //Loading connections + if(opts.count(ListConns) || opts.count(ExportToDbms) || opts.count(ImportDb) || opts.count(Diff)) + { + conn_conf = new ConnectionsConfigWidget; + conn_conf->loadConfiguration(); + conn_conf->getConnections(connections, false); + } + //Loading general and relationship settings when exporting to image formats + else if(opts.count(ExportToPng) || opts.count(ExportToSvg)) + { + general_conf = new GeneralConfigWidget; + rel_conf = new RelationshipConfigWidget; + + general_conf->loadConfiguration(); + rel_conf->loadConfiguration(); + } + + //Creating the export/import/diff helpers when one of the operations are specified + if(opts.count(ExportToDbms) || opts.count(ExportToFile) || + opts.count(ExportToPng) || opts.count(ExportToSvg) || + opts.count(ExportToDict) || opts.count(ImportDb) || + opts.count(Diff)) + { + export_hlp = new ModelExportHelper; + import_hlp = new DatabaseImportHelper; + diff_hlp = new ModelsDiffHelper; + } + + if(opts.empty() || opts.count(Help)) + showMenu(); + else + { + QString curr_op_mode; + int exp_mode_cnt = 0, other_modes_cnt = 0; + bool fix_model = (opts.count(FixModel) > 0), + upd_mime = (opts.count(DbmMimeType) > 0), + import_db = (opts.count(ImportDb) > 0), + diff = (opts.count(Diff) > 0), + create_configs= (opts.count(CreateConfigs) > 0), + list_conns = (opts.count(ListConns) > 0), + export_dbms = (opts.count(ExportToDbms) > 0); + + for(auto &itr : accepted_opts) + { + if(itr.first == Attributes::Connection) + continue; + + if(opts.count(itr.first)) + { + curr_op_mode = itr.first; + + if(itr.first == ExportToFile || itr.first == ExportToPng || + itr.first == ExportToSvg || itr.first == ExportToDbms || + itr.first == ExportToDict) + exp_mode_cnt++; + else + other_modes_cnt++; + } + } + + if(opts.count(ZoomFactor)) + zoom=opts[ZoomFactor].toDouble()/static_cast(100); + + if(other_modes_cnt==0 && exp_mode_cnt==0) + throw Exception(tr("No operation mode was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if((exp_mode_cnt > 0 && (fix_model || upd_mime || import_db || diff || create_configs || list_conns)) || (exp_mode_cnt==0 && other_modes_cnt > 1)) + throw Exception(tr("Multiple operation modes were specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!fix_model && !upd_mime && exp_mode_cnt > 1) + throw Exception(tr("Multiple export modes were specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!list_conns && !upd_mime && !import_db && !diff && !create_configs && !opts.count(Input)) + throw Exception(tr("No input file was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(import_db && !opts.count(InputDb)) + throw Exception(tr("No input database was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!opts.count(ExportToDbms) && !upd_mime && !list_conns && !diff && !create_configs && !opts.count(Output)) + throw Exception(tr("No output file was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!opts.count(ExportToDbms) && !upd_mime && !import_db && !list_conns && !create_configs && + opts.count(Input) && opts.count(Output) && + QFileInfo(opts[Input]).absoluteFilePath() == QFileInfo(opts[Output]).absoluteFilePath()) + throw Exception(tr("The input file must be different from the output!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(ExportToDbms) && !opts.count(ConnAlias) && + (!opts.count(Host) || !opts.count(User) || !opts.count(Passwd) || !opts.count(InitialDb)) ) + throw Exception(tr("Incomplete connection information!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(ExportToPng) && (zoom < ModelWidget::MinimumZoom || zoom > ModelWidget::MaximumZoom)) + throw Exception(tr("Invalid zoom specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(upd_mime && opts[DbmMimeType]!=Install && opts[DbmMimeType]!=Uninstall) + throw Exception(tr("Invalid action specified to mime type update option!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(create_configs && opts.count(Force) && opts.count(MissingOnly)) + throw Exception(tr("The options `%1' and `%2' can't be used together when handling configuration files!").arg(Force).arg(MissingOnly), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(DependenciesSql) || opts.count(ChildrenSql)) + { + if(!opts.count(ExportToFile) || (opts.count(ExportToFile) && !opts.count(Split))) + throw Exception(tr("The options `%1' and `%2' must be used together with the split mode option `%3'!").arg(DependenciesSql, ChildrenSql, Split), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + else if(opts.count(DependenciesSql) && opts.count(ChildrenSql)) + throw Exception(tr("The options `%1' and `%2' can't be used at the same time!").arg(DependenciesSql, ChildrenSql), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + if(diff) + { + if(!opts.count(Input) && !opts.count(InputDb)) + throw Exception(tr("No input file or database was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(Input) && opts.count(InputDb)) + throw Exception(tr("The input file and the input database can't be used at the same time!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!opts.count(CompareTo)) + throw Exception(tr("No database to be compared was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!opts.count(SaveDiff) && !opts.count(ApplyDiff)) + throw Exception(tr("No diff action (save or apply) was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(SaveDiff) && opts[Output].isEmpty()) + throw Exception(tr("No output file for the diff code was specified!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(PartialDiff) && !opts[Input].count() && (opts.count(StartDate) || opts.count(EndDate))) + throw Exception(tr("The date filters are allowed only on partial diff using an input model!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(PartialDiff) && opts.count(FilterObjects) && (opts.count(StartDate) || opts.count(EndDate))) + throw Exception(tr("The date filters and object filters can't be used together!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(opts.count(PartialDiff) && !opts.count(FilterObjects) && !opts.count(StartDate) && !opts.count(EndDate)) + throw Exception(tr("Partial diff enabled but no object filter was provided!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + // For partial diff we force the --only-matching option and --force-children = all + if(opts.count(PartialDiff)) + { + opts[ForceChildren] = AllChildren; + opts[OnlyMatching] = ""; + } + + // Validating the date formats in the provided start/end dates + QDateTime *dates[2] = { &start_date, &end_date }; + QStringList dt_params = { StartDate, EndDate }; + + for(int idx = 0; idx < 2; idx++) + { + if(opts.count(dt_params[idx])) + { + *dates[idx] = QDateTime::fromString(opts[dt_params[idx]], Qt::ISODate); + + if(!dates[idx]->isValid()) + throw Exception(tr("Invalid date format `%1' in option `%2'!").arg(opts[dt_params[idx]]).arg(dt_params[idx]), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + + /* If any of the dates are correctly parsed we need to force + * the signature name matching, the forced filtering of all table children objects + * and the only-matching option, so the objects can be correctly retrieved from + * the destination database */ + if(start_date.isValid() || end_date.isValid()) + { + parsed_opts.erase(MatchByName); + parsed_opts[ForceChildren] = AllChildren; + parsed_opts[OnlyMatching] = ""; + } + } + + //Converting input and output files to absolute paths to avoid that they are read/written on the app's working dir + if(opts.count(Input)) + opts[Input]=QFileInfo(opts[Input]).absoluteFilePath(); + + if(opts.count(Output)) + opts[Output]=QFileInfo(opts[Output]).absoluteFilePath(); + + /* Special treatment for filter parameters: + * Since it can be specified several filter parameter we need to join + * everything in a single string list so it can be passed to the import helper correctly */ + if(opts.count(FilterObjects)) + { + opts.erase(FilterObjects); + + for(auto &op : opts) + { + if(op.first.contains(FilterObjects)) + obj_filters.append(op.second); + } + } + + /* Performing a final validation on the parsed options which consists + * in check if all provided options are compatible with the operation mode selected */ + QStringList acc_opts = accepted_opts[curr_op_mode]; + QString long_opt; + + // Diff, import and export (to DBMS) share the same connection options + if(diff || import_db || export_dbms) + acc_opts.append(accepted_opts[Attributes::Connection]); + + // Diff also accepts all import parameters + if(diff) + acc_opts.append(accepted_opts[ImportDb]); + + for(auto &itr : opts) + { + long_opt = itr.first; + + if(long_opt == curr_op_mode || long_opt == Silent) + continue; + + /* Before validate the option we need to remove any appended number to the option name + * This happens for options related to objects filters and connections */ + long_opt.remove(QRegularExpression("[0-9]+$")); + + if(!acc_opts.contains(long_opt)) + throw Exception(tr("The option `%1' is not accepted by the operation mode `%2'!").arg(long_opt).arg(curr_op_mode), + ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + parsed_opts = opts; + } +} + +int PgModelerCliApp::exec() +{ + try + { + if(!parsed_opts.empty()) + { + showVersionInfo(); + + if(parsed_opts.count(ListConns)) + listConnections(); + else if(parsed_opts.count(FixModel)) + fixModel(); + else if(parsed_opts.count(DbmMimeType)) + updateMimeType(); + else if(parsed_opts.count(CreateConfigs)) + createConfigurations(); + else if(parsed_opts.count(ImportDb)) + importDatabase(); + else if(parsed_opts.count(Diff)) + diffModelDatabase(); + else + exportModel(); + } + + return 0; + } + catch(Exception &e) + { + throw e; + } +} + +void PgModelerCliApp::updateProgress(int progress, QString msg, ObjectType) +{ + if(progress > 0) + printMessage(QString("[%1%] ").arg(progress > 100 ? 100 : progress) + msg); + else + printMessage(msg); +} + +void PgModelerCliApp::printIgnoredError(QString err_cod, QString err_msg, QString cmd) +{ + printText(); + printText(tr("** Error code `%1' found and ignored. Proceeding with export.").arg(err_cod)); + printText(tr("** Command: %1").arg(cmd)); + printText(err_msg); + printText(); +} + +void PgModelerCliApp::handleObjectAddition(BaseObject *object) +{ + BaseGraphicObject *graph_obj=dynamic_cast(object); + + if(graph_obj) + { + ObjectType obj_type=graph_obj->getObjectType(); + QGraphicsItem *item=nullptr; + + switch(obj_type) + { + case ObjectType::Table: + item=new TableView(dynamic_cast(graph_obj)); + break; + + case ObjectType::ForeignTable: + item=new TableView(dynamic_cast(graph_obj)); + break; + + case ObjectType::View: + item=new GraphicalView(dynamic_cast(graph_obj)); + break; + + case ObjectType::Relationship: + case ObjectType::BaseRelationship: + item=new RelationshipView(dynamic_cast(graph_obj)); + break; + + case ObjectType::Schema: + item=new SchemaView(dynamic_cast(graph_obj)); + break; + + default: + item=new StyledTextboxView(dynamic_cast(graph_obj)); + break; + } + + scene->addItem(item); + + if(BaseTable::isBaseTable(obj_type)) + dynamic_cast(graph_obj->getSchema())->setModified(true); + } +} + + +void PgModelerCliApp::handleObjectRemoval(BaseObject *object) +{ + BaseGraphicObject *graph_obj=dynamic_cast(object); + + if(graph_obj) + { + scene->removeItem(dynamic_cast(graph_obj->getOverlyingObject())); + + //Updates the parent schema if the removed object were a table or view + if(graph_obj->getSchema() && BaseTable::isBaseTable(graph_obj->getObjectType())) + dynamic_cast(graph_obj->getSchema())->setModified(true); + } +} + + +void PgModelerCliApp::extractObjectXML() +{ + QString buf, lin, def_xml, end_tag; + QTextStream ts; + int start=-1, end=-1; + bool open_tag=false, close_tag=false, is_rel=false, short_tag=false, end_extract_rel=false, is_change_log=false; + + printMessage(tr("Extracting objects' XML...")); + buf.append(UtilsNs::loadFile(parsed_opts[Input])); + + // Extracting pgModeler version from input model + QRegularExpression ver_expr(AttributeExpr.arg(Attributes::PgModelerVersion)); + QRegularExpressionMatch match; + + QStringList capt_txts; + match = ver_expr.match(buf); + start = match.capturedStart(); + capt_txts = match.capturedTexts(); + model_version = !capt_txts.isEmpty() ? capt_txts.at(0) : ""; + model_version.remove(Attributes::PgModelerVersion); + model_version.remove(QRegularExpression("(\\\"|\\=| )+")); + + if(!model_version.contains(QRegularExpression("(\\d\\.\\d\\.\\d)((\\-)(alpha|beta)(\\d))?"))) + { + printMessage(tr("** WARNING: Couldn't determine the pgModeler version in which the input model was created!")); + printMessage(tr(" Some fix actions that depend on the model version will not be applied!")); + model_version.clear(); + } + + QRegularExpressionMatch header_match; + QRegularExpression header_regexp(QString("^<\\?xml.+<%1").arg(Attributes::DbModel), + QRegularExpression::DotMatchesEverythingOption | + QRegularExpression::DontCaptureOption); + + //Check if the file contains a valid header (for .dbm file) + /* ATTENTION: PCRE2 (base implementation of QRegularExpression) limits the amount of groups (defined by (expr) ) to + * be captured. So, in large buffer expression such (.)+ must be used with caution. In some cases the matching won't + * work even if it works on smaller text buffers. The workaround is to use a small portion of the buffer as well as avoiding + * capture groups. In the case below we just need to know the position of a certain regexp in the buffer, + * so we use a small portion of the entire buffer as subject of the searching. + * + * Reference: https://stackoverflow.com/questions/52980957/qregularexpression-lazy-matching-not-working-for-very-large-strings */ + header_match = header_regexp.match(buf.mid(0, 5000)); + start = header_match.capturedStart(); + + if(start < 0) + throw Exception(tr("Invalid input file! It seems that is not a pgModeler generated model or the file is corrupted!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Extracting layers informations from the tag + QRegularExpression dbm_regexp = QRegularExpression(TagExpr.arg(Attributes::DbModel)), + + db_end_regexp = QRegularExpression(EndTagExpr.arg(Attributes::Database)), + + //[schema].[func_name](...OUT [type]...) + func_signature=QRegularExpression("(\")(.)+(\\.)(.)+(\\()(.)*(OUT )(.)+(\\))(\")"), + + //[,]OUT [schema].[type] + out_param=QRegularExpression("(,)?(OUT )([a-z]|[0-9]|(\\.)|(\\_)|(\\-)|( )|(\\[)|(\\])|("))+((\\()([0-9])+(\\)))?"); + + int attr_start =-1, attr_end = -1, dbm_start = -1; + QString aux_buf, + layers, active_layers, attr_expr = "(%1)( )*(=)(\")"; + QList act_layers_ids; + + match = dbm_regexp.match(buf); + dbm_start = match.capturedStart(); + aux_buf = buf.mid(dbm_start, buf.indexOf(db_end_regexp) - dbm_start); + + //Layers names + attr_start = aux_buf.indexOf(Attributes::Layers); + attr_end = aux_buf.indexOf(Attributes::ActiveLayers); + layers = aux_buf.mid(attr_start, attr_end - attr_start); + layers.remove(QRegularExpression(attr_expr.arg(Attributes::Layers))); + layers.remove('"'); + + QStringList aux_layers = layers.trimmed().split(',', Qt::SkipEmptyParts); + + /* In 0.9.x there was a "Default" layer created automatically in the model + * In order to not losing the correct layer arrangement, we include that default + * layer in the list of layers in the model so the objects doesn't put in the + * wrong layer when loaded after the model is fixed */ + if(model_version < "1.0.0" && !aux_layers.contains("Default")) + aux_layers.prepend("Default,"); + + model->setLayers(aux_layers); + + //Active layers + attr_start = attr_end; + attr_end = aux_buf.indexOf(Attributes::LayerNameColors, attr_start); + + if(attr_end < 0) + attr_end = aux_buf.indexOf(">", attr_start); + + active_layers = aux_buf.mid(attr_start, attr_end - attr_start); + active_layers.remove(QRegularExpression(attr_expr.arg(Attributes::ActiveLayers))); + active_layers.remove('"'); + active_layers.replace(',', ';'); + + for(auto &id : active_layers.trimmed().split(';', Qt::SkipEmptyParts)) + act_layers_ids.push_back(id.toUInt()); + + model->setActiveLayers(act_layers_ids); + buf.remove(0, dbm_start); + + //Checking if the header ends on a role declaration + start = buf.indexOf(QString("<%1").arg(Attributes::Role)), + end = buf.lastIndexOf(QString("/%1>").arg(Attributes::Role)); + + // If we found role declarations we clear the header until there + if(start >= 0 && end > start) + buf.remove(0, start); + else + // Instead, we clear the header until the starting of database declaration + buf.remove(0, buf.indexOf(QString("<%1").arg(Attributes::Database))); + + buf.remove(QString("<\\%1>").arg(Attributes::DbModel)); + ts.setString(&buf); + + //Extracts the objects xml line by line + while(!ts.atEnd()) + { + lin=ts.readLine(); + + /* Collecting changelog entries if present and storing in a separated buffer + * so it can be restored in the fixed model during objects' reconstruction */ + if(!is_change_log && lin.contains(TagExpr.arg(Attributes::Changelog))) + is_change_log = true; + + if(is_change_log) + { + changelog.append(lin); + + if(lin.contains(EndTagExpr.arg(Attributes::Changelog))) + is_change_log = false; + else + continue; + } + + /* Special case for empty tags like , they will be converted to + in order to be correctly extracted further. Currently only language has this + behaviour, so additional object may be added in the future. */ + if(lin.contains(QString("<%1").arg(BaseObject::getSchemaName(ObjectType::Language)))) + { + lin=lin.simplified(); + + if(lin.contains("/>")) + lin.replace("/>", QString(">").arg(BaseObject::getSchemaName(ObjectType::Language))); + } + /* Special case for function signatures. In previous releases, the function's signature was wrongly + including OUT parameters and according to docs they are not part of the signature, so it is needed + to remove them if the current line contains a valid signature with parameters. */ + else if(lin.contains(func_signature)) + lin.remove(out_param); + + if(is_rel && (((short_tag && lin.contains("/>")) || + (lin.contains("[a-z]+") && !containsRelAttributes(lin))))) + open_tag=close_tag=true; + else + { + //If the line contains an objects open tag + if(lin.contains(QRegularExpression("^(((\n)|(\t))*(<))")) && !open_tag) + { + //Check the flag indicating an open tag + open_tag=true; + + start=lin.indexOf('<'); + end=lin.indexOf(' '); + if(end < 0) end=lin.indexOf('>'); + + //Configures the end tag with the same word extracted from open tag + end_tag=lin.mid(start, end-start+1).trimmed(); + end_tag.replace("<", "')) + end_tag+=">"; + + /* Checking if the line start a relationship. Relationships are treated + a little different because they can be empty or + contain open and close tags */ + is_rel=lin.contains(Attributes::Relationship); + + if(is_rel) + { + end_extract_rel=short_tag=false; + + while(!end_extract_rel && !ts.atEnd()) + { + def_xml+=lin + "\n"; + lin=lin.trimmed(); + + //Checking if the current line is the end of a short-tag relationship + if(!short_tag && !lin.startsWith('<') && lin.endsWith("/>")) + short_tag=true; + + end_extract_rel=((!short_tag && lin.contains(end_tag)) || short_tag); + + if(!end_extract_rel) + lin=ts.readLine(); + } + + close_tag=true; + } + else + close_tag=lin.contains(end_tag); + } + else if(open_tag && lin.contains(end_tag)) + close_tag=true; + } + + if(!is_rel && !lin.isEmpty()) + def_xml+=lin + "\n"; + else if(lin.isEmpty()) + def_xml+="\n"; + + //If the iteration reached the end of the object's definition + if(open_tag && close_tag) + { + //Pushes the extracted definition to the list (only if not empty) + if(def_xml!="\n") + { + objs_xml.push_back(def_xml); + buffer_size += def_xml.size(); + } + + def_xml.clear(); + open_tag=close_tag=is_rel=false; + } + } +} + +void PgModelerCliApp::recreateObjects() +{ + QStringList fail_objs, constr, list; + QString xml_def, aux_def, start_tag = "<%1", end_tag = "", aux_tag, type_tag = " types={ ObjectType::Index, ObjectType::Trigger, ObjectType::Rule }; + attribs_map attribs, fmt_ext_names; + bool use_fail_obj=false; + unsigned tries=0, max_tries=parsed_opts[FixTries].toUInt(); + int start_pos=-1, end_pos=-1, len=0; + qint64 curr_size = 0; + + printMessage(tr("Recreating objects...")); + + if(max_tries==0) + max_tries=1; + + model->createSystemObjects(false); + + while(!objs_xml.isEmpty()) + { + //If there are failed objects and the flag is set + if(use_fail_obj && !fail_objs.isEmpty()) + { + xml_def = fail_objs.front(); + fail_objs.pop_front(); + use_fail_obj=false; + } + else + { + xml_def = objs_xml.front(); + objs_xml.pop_front(); + fixObjectAttributes(xml_def); + } + + /* Replacing the tags [restartParser(); + xmlparser->loadXMLBuffer(xml_def); + obj_type=BaseObject::getObjectType(xmlparser->getElementName()); + + xmlparser->getElementAttributes(attribs); + + if(obj_type==ObjectType::Database) + model->configureDatabase(attribs); + else + { + if(obj_type==ObjectType::Table) + { + //Before create a table extract it's foreign keys + list=extractForeignKeys(xml_def); + + /* If fks were extracted insert them on the main constraints list + * and restarts the XMLParser with the modified buffer */ + if(!list.isEmpty()) + { + constr.append(list); + xmlparser->restartParser(); + xmlparser->loadXMLBuffer(xml_def); + } + } + + //Discarding fk relationships + if(obj_type!=ObjectType::Relationship || + (obj_type==ObjectType::Relationship && !xml_def.contains(QString("\"%1\"").arg(Attributes::RelationshipFk)))) + { + object=model->createObject(obj_type); + + if(object) + { + if(!dynamic_cast(object) && obj_type!=ObjectType::Relationship && obj_type!=ObjectType::BaseRelationship) + model->addObject(object); + + curr_size += xml_def.size(); + printMessage(QString("[%1%] %2") + .arg(static_cast((curr_size/static_cast(buffer_size)) * 100)) + .arg(tr("Object recreated: `%1' (%2)")) + .arg(object->getName(true)) + .arg(object->getTypeName())); + + /* Special case for extensions: + * Before pgModeler 0.9.4-alpha1 the types handled by extension (for example hstore, ltree, etc) were + * registered in the PgSqlType as user-defined data type without their schemas names prepended. This + * was causing lot of troubles importing databases in which extension data types were being used. The + * solution was to adjust the extension type names in such a way to prepend schema names. So here we + * store the schema-qualified extension name in a special map where the key is the name of the extension + * without the schema name, this way search the tags [getObjectType() == ObjectType::Extension && dynamic_cast(object)->handlesType()) + fmt_ext_names[object->getName()] = object->getName(true, true); + } + + //For each sucessful created object the method will try to create a failed one + use_fail_obj=(!fail_objs.isEmpty()); + } + else if(obj_type == ObjectType::Relationship && + xml_def.contains(QString("\"%1\"").arg(Attributes::RelationshipFk))) + curr_size += xml_def.size(); + + /* Additional step to extract indexes/triggers/rules from within tables/views + * and putting their xml on the list of object to be created */ + if(BaseTable::isBaseTable(obj_type) && xml_def.contains(QRegularExpression("(<)(index|trigger|rule)"))) + { + for(auto &type : types) + { + do + { + //Checking where the object starts and ends + aux_tag=start_tag.arg(BaseObject::getSchemaName(type)); + start_pos=xml_def.indexOf(aux_tag); + end_pos=(start_pos >=0 ? xml_def.indexOf(end_tag.arg(BaseObject::getSchemaName(type))) : -1); + + if(start_pos >=0 && end_pos >= 0) + { + //Extracts the xml code + len=(end_pos - start_pos) + end_tag.arg(BaseObject::getSchemaName(type)).length() + 1; + aux_def=xml_def.mid(start_pos, len); + + //Remove the code from original table's definition + xml_def.remove(start_pos, len); + + //If the extract object doesn't contains the 'table=' attribute it'll be added. + if(!aux_def.contains("table=")) + { + aux_def.replace(aux_tag, QString("%1 table=\"%2\"") + .arg(aux_tag, UtilsNs::convertToXmlEntities(object->getName(true)))); + } + + objs_xml.push_back(aux_def); + } + } + while(start_pos >= 0); + } + } + } + } + catch(Exception &e) + { + if(obj_type!=ObjectType::Database) + { + QString error = tr("** WARNING: Failed to recreate the object!"); + + fail_objs.push_back(xml_def); + printText(QString("\n** %1\n ** %2").arg(error, e.getErrorMessage())); + error += QString("%1\n\n%2\n***").arg(e.getExceptionsText(), xml_def); + + // Store the error in the log file as well as the XML code of the failed object + QFile fix_log; + fix_log.setFileName(GlobalAttributes::getTemporaryFilePath(ModelFixLog)); + fix_log.open(QFile::Append); + fix_log.write(error.toUtf8()); + fix_log.close(); + + has_fix_log = true; + } + else + throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + + if(objs_xml.isEmpty() && (!fail_objs.isEmpty() || !constr.isEmpty())) + { + tries++; + + //If the maximum creation tries reaches the maximum value + if(tries > max_tries) + { + //Outputs the code of the objects that wasn't created + printText(); + printText(tr("** A total of %1 object(s) couldn't be fixed: ").arg(fail_objs.size())); + + while(!fail_objs.isEmpty()) + { + printText(fail_objs.front()); + fail_objs.pop_front(); + } + + break; + } + else + { + printMessage(tr("** WARNING: There are objects that maybe can't be fixed. Trying again... (tries %1/%2)").arg(tries).arg(max_tries)); + model->validateRelationships(); + objs_xml = fail_objs; + objs_xml.append(constr); + fail_objs.clear(); + constr.clear(); + } + } + } + + // Fixing the roles memberships. + Role *role = nullptr, *mem_role = nullptr; + bool member_fixed = false; + + for(auto &rl : member_roles) + { + role = model->getRole(rl.first); + + if(!role) + { + printMessage(tr("** WARNING: Couldn't find the role `%1'! Ignoring it...").arg(rl.first)); + continue; + } + + for(auto &name : rl.second) + { + mem_role = model->getRole(name); + + if(!mem_role) + { + printMessage(tr("** WARNING: Couldn't find the role `%1' of `%2`! Igorning it...").arg(name, rl.first)); + continue; + } + + role->addRole(Role::MemberRole, mem_role); + member_fixed = true; + } + } + + if(member_fixed) + { + printMessage(tr("** WARNING: Roles memberships were fixed but their creation order is not guaranteed!")); + printMessage(tr(" It may be necessary to run the fix tool again but now on the file `%1'.").arg(parsed_opts[Output])); + } + + // Reconstructing the persisted change log if present + if(!changelog.isEmpty()) + { + model->setPersistedChangelog(true); + xmlparser->loadXMLBuffer(changelog); + + if(xmlparser->accessElement(XmlParser::ChildElement)) + { + do + { + xmlparser->getElementAttributes(attribs); + model->addChangelogEntry(attribs[Attributes::Signature], attribs[Attributes::Type], + attribs[Attributes::Action], attribs[Attributes::Date]); + } + while(xmlparser->accessElement(XmlParser::NextElement)); + } + } +} + +void PgModelerCliApp::fixObjectAttributes(QString &obj_xml) +{ + //Placing objects , , outside of
+ if(!obj_xml.startsWith(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Tablespace))) && + obj_xml.startsWith(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Table)))) + { + int start_idx=-1, end_idx=-1, len=0; + ObjectType obj_types[3]={ ObjectType::Rule, ObjectType::Trigger, ObjectType::Index }; + QString curr_tag, curr_end_tag, def, tab_name, sch_name, + name_attr="name=\"", + sch_name_attr=TagExpr.arg(BaseObject::getSchemaName(ObjectType::Schema)) + " " + name_attr; + + //Extracting the table's name + start_idx=obj_xml.indexOf(name_attr); + end_idx=obj_xml.indexOf("\"", start_idx + name_attr.size()); + tab_name=obj_xml.mid(start_idx, end_idx - start_idx).remove(name_attr); + + //Extracting the table's schema name + start_idx=obj_xml.indexOf(sch_name_attr); + end_idx=obj_xml.indexOf('"', start_idx + sch_name_attr.size()); + sch_name=obj_xml.mid(start_idx, end_idx - start_idx).remove(sch_name_attr); + + //Configuring the table=[name] attribute to be included on rule objects + tab_name=QString("table=\"%1.%2\"").arg(sch_name).arg(tab_name); + + for(unsigned idx=0; idx < 3; idx++) + { + curr_tag=TagExpr.arg(BaseObject::getSchemaName(obj_types[idx])); + curr_end_tag=EndTagExpr.arg(BaseObject::getSchemaName(obj_types[idx])) + ">"; + start_idx=obj_xml.indexOf(curr_tag); + + while(start_idx >=0) + { + end_idx=obj_xml.indexOf(curr_end_tag); + len=(end_idx - start_idx) + curr_end_tag.size(); + def=obj_xml.mid(start_idx, len) + "\n\n"; + obj_xml.remove(start_idx, len); + + //If the object is a rule include the table attribute + if(def.startsWith(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Rule)))) + { + start_idx=def.indexOf('>'); + def.replace(start_idx, 1, " " + tab_name + ">"); + } + + start_idx=obj_xml.indexOf(curr_tag); + + if(!def.isEmpty()) + //Puts the object's defintion to the list in order to be evaluated in the main process + objs_xml.push_back(def); + } + } + } + + //Remove recheck attribute from tags. + if(obj_xml.contains(TagExpr.arg(Attributes::Element))) + obj_xml.remove(QRegularExpression(AttributeExpr.arg("recheck"))); + + //Remove values greater-op, less-op, sort-op or sort2-op from ref-type attribute from tags. + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Operator)))) + { + obj_xml.remove("greater-op"); + obj_xml.remove("less-op"); + obj_xml.remove("sort-op"); + obj_xml.remove("sort2-op"); + } + + //Replacing attribute owner by onwer-col for sequences + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Sequence)))) + obj_xml.replace(QRegularExpression(QString("(%1)( )*(=)(\")").arg(Attributes::Owner)), QString("%1 = \"").arg(Attributes::OwnerColumn)); + + /* Remove sysid attribute and encrypted from tags and storing the referenced roles (ref-roles) + * for later re-assignment. */ + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Role)))) + { + obj_xml.remove(QRegularExpression(AttributeExpr.arg("sysid"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("encrypted"))); + + QRegularExpression ref_roles_expr = QRegularExpression(QString("(<%1)(.)+(%2)( )*(=)(\")(%3)(\")(.)+(>)").arg(Attributes::Roles, Attributes::RoleType, Attributes::Refer)); + QRegularExpressionMatch match; + int pos = -1; + + match = ref_roles_expr.match(obj_xml); + pos = match.capturedStart(); + + if(pos >= 0) + { + QString buf = obj_xml.mid(pos, match.capturedLength()), + name_attr = "name=\"", role_name; + int start_idx = 0, end_idx = 0; + + // Extracting the role name + start_idx = obj_xml.indexOf(name_attr); + end_idx = obj_xml.indexOf("\"", start_idx + name_attr.size()); + role_name = obj_xml.mid(start_idx, end_idx - start_idx).remove(name_attr); + + // Removing the element + obj_xml.remove(pos, match.capturedLength()); + + // Retrieve the name of the ref-roles + buf.remove(QRegularExpression("^(.)+(names=\")")); + buf.remove(buf.indexOf("\""), buf.size()); + + /* Storing the association between the current role and the ref-roles + * in a map for further processing */ + for(auto &rl_name : buf.split(',', Qt::SkipEmptyParts)) + member_roles[rl_name].append(role_name); + } + } + + //Replace tag by on tags. + if(obj_xml.contains(TagExpr.arg("usertype"))) + { + obj_xml.replace(TagExpr.arg(Attributes::Parameter), TagExpr.arg(Attributes::TypeAttribute)); + obj_xml.replace(EndTagExpr.arg(Attributes::Parameter), EndTagExpr.arg(Attributes::TypeAttribute)); + + // Fixing the enumeration type labels + if(!model_version.isEmpty() && model_version <= "0.9.4-beta1") + { + /* Until pgModeler 0.9.3, enum labels separators where commas. + * In pgModeler 0.9.4, enum labels separators where UtilsNs::DataSeparator */ + QString sep = (model_version == "0.9.4-beta1" ? UtilsNs::DataSeparator : ","), + values, labels; + QRegularExpression enum_start_expr("(" + TagExpr.arg(Attributes::EnumType) + ")( )*(values)( )*(=)( )*(\\\")"), + enum_end_expr("(\\\")( )*(\\/>)"), + enum_tag_expr("(" + TagExpr.arg(Attributes::EnumType) + ")(.)+(/>)"); + int start = -1, end = -1; + QRegularExpressionMatch match; + + match = enum_start_expr.match(obj_xml); + start = match.capturedStart() + match.capturedLength(); + + match = enum_end_expr.match(obj_xml, start); + end = match.capturedStart(); + values = obj_xml.mid(start, end - start); + + if(!values.isEmpty()) + { + // Converting each value extract into a separated tag + for(auto &label : values.split(sep, Qt::SkipEmptyParts)) + labels.append(QString("\t<%1 label=\"%2\"/>\n").arg(Attributes::EnumType, label)); + + obj_xml.replace(enum_tag_expr, labels); + } + } + } + + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Relationship)))) + { + //Remove auto-sufix, src-sufix, dst-sufix, col-indexes, constr-indexes, attrib-indexes from tags. + obj_xml.remove(QRegularExpression(AttributeExpr.arg("auto-sufix"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("src-sufix"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("dst-sufix"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("col-indexes"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("constr-indexes"))); + obj_xml.remove(QRegularExpression(AttributeExpr.arg("attrib-indexes"))); + + obj_xml.replace("line-color", Attributes::CustomColor); + } + + //Renaming the tag to on indexes + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Index)))) + { + obj_xml.replace(TagExpr.arg(Attributes::Condition), TagExpr.arg(Attributes::Predicate)); + obj_xml.replace(EndTagExpr.arg(Attributes::Condition), EndTagExpr.arg(Attributes::Predicate)); + } + + //Renaming the attribute default to default-value on domain + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Domain)))) + obj_xml.replace(Attributes::Default, Attributes::DefaultValue); + + //Renaming the tag to + if(obj_xml.contains(TagExpr.arg("grant"))) + { + obj_xml.replace(TagExpr.arg("grant"), TagExpr.arg(BaseObject::getSchemaName(ObjectType::Permission))); + obj_xml.replace(EndTagExpr.arg("grant"), EndTagExpr.arg(BaseObject::getSchemaName(ObjectType::Permission))); + } + + //Replace the constraint attribute and tag expression by constraint tag in . + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Domain))) && + obj_xml.contains(TagExpr.arg(Attributes::Expression))) + { + int start_idx=-1, end_idx=-1; + QRegularExpression regexp = QRegularExpression(AttributeExpr.arg(Attributes::Constraint)); + QString constr_name; + QRegularExpressionMatch match; + + match = regexp.match(obj_xml); + + /* In pgModeler 0.8.2, there wasn't the constraint attribute in domains + * so we just create a name for it based on the domain's name */ + if(!match.hasMatch()) + { + QString name_attr="name=\""; + start_idx = obj_xml.indexOf(name_attr); + end_idx = obj_xml.indexOf("\"", start_idx + name_attr.size()); + constr_name = obj_xml.mid(start_idx, end_idx - start_idx).remove(name_attr) + "_ck"; + } + else + { + constr_name = match.capturedTexts().at(0); + constr_name.remove(QString("%1=\"").arg(Attributes::Constraint)); + constr_name.remove(constr_name.length() - 1, 1); + obj_xml.remove(QRegularExpression(AttributeExpr.arg(Attributes::Constraint))); + } + + start_idx = obj_xml.indexOf(TagExpr.arg(Attributes::Expression)); + obj_xml.insert(start_idx, QString("\n\t\n\t\t").arg(constr_name)); + + end_idx = obj_xml.indexOf(EndTagExpr.arg(Attributes::Expression)); + obj_xml.insert(end_idx + EndTagExpr.arg(Attributes::Expression).length() + 1, "\n\t\n"); + } + + //Replace the deprecated attribute hide-ext-attribs="false|true" from
and by collapse-mode="0|1" + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Table))) || + obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::View)))) + { + obj_xml.replace(QString("%1=\"false\"").arg(Attributes::HideExtAttribs), QString("%1=\"0\"").arg(Attributes::CollapseMode)); + obj_xml.replace(QString("%1=\"true\"").arg(Attributes::HideExtAttribs), QString("%1=\"1\"").arg(Attributes::CollapseMode)); + } + + //Remove the usage of IN keyword in functions' signatures since it is the default if absent + QRegularExpression regexp = QRegularExpression(AttributeExpr.arg(Attributes::Signature)); + QRegularExpressionMatch match; + int sig_idx = -1, len = 0; + QString signature, in_keyw = "IN "; + + match = regexp.match(obj_xml); + sig_idx = match.capturedStart(); + + while(sig_idx >= 0) + { + signature = obj_xml.mid(sig_idx, match.capturedLength()); + len = signature.length(); + + if(!signature.contains(in_keyw)) + { + match = regexp.match(obj_xml, sig_idx + len); + sig_idx = match.capturedStart(); + continue; + } + + signature.remove(in_keyw); + obj_xml.remove(sig_idx, len); + obj_xml.insert(sig_idx, signature); + + match = regexp.match(obj_xml, sig_idx + len); + sig_idx = match.capturedStart(); + } + + //Rename the attribute layer to layers + QRegularExpression layer_regexp("(layer)( )*(=)"); + if(obj_xml.contains(QRegularExpression(layer_regexp))) + obj_xml.replace(layer_regexp, Attributes::Layers + "="); + + //Fix the references to op. classes and families if needed + fixOpClassesFamiliesReferences(obj_xml); +} + +void PgModelerCliApp::fixOpClassesFamiliesReferences(QString &obj_xml) +{ + ObjectType ref_obj_type; + + if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Index))) || + obj_xml.contains(QRegularExpression(QString("(%1)(.)+(type=)(\")(%2)(\")") + .arg(TagExpr.arg(BaseObject::getSchemaName(ObjectType::Constraint))) + .arg(Attributes::ExConstr)))) + ref_obj_type=ObjectType::OpClass; + else if(obj_xml.contains(TagExpr.arg(BaseObject::getSchemaName(ObjectType::OpClass)))) + ref_obj_type=ObjectType::OpFamily; + else + return; + + QString ref_obj_name=BaseObject::getSchemaName(ref_obj_type); + if(!obj_xml.contains(TagExpr.arg(ref_obj_name))) + return; + + QString obj_name, aux_obj_name, signature=("%1 USING %2"); + QRegularExpression sign_regexp=QRegularExpression(AttributeExpr.arg("signature")); + QRegularExpressionMatch match; + QStringList index_types; + int pos=0; + + obj_xml.replace(TagExpr.arg(ref_obj_name) + " name=", + TagExpr.arg(ref_obj_name) +" signature="); + + index_types = IndexingType::getTypes(); + + do + { + match = sign_regexp.match(obj_xml, pos); + pos = match.capturedStart(); + + if(pos >= 0) + { + //Extracting the signature attribute + obj_name=obj_xml.mid(pos, match.capturedLength()); + + //Removing useless portions signature=" in order to retrive only the object's name + obj_name.remove(QRegularExpression("(signature)( )*(=)")); + obj_name.remove('"'); + + //Transforming xml entity for quote into the char + obj_name.replace(UtilsNs::EntityQuot, "\""); + + for(auto &idx_type : index_types) + { + aux_obj_name=signature.arg(obj_name).arg(idx_type); + + if(model->getObjectIndex(aux_obj_name, ref_obj_type) >= 0) + { + //Replacing the old signature with the corrected form + aux_obj_name.replace("\"", UtilsNs::EntityQuot); + obj_xml.replace(pos, match.capturedLength(), QString("signature=\"%1\"").arg(aux_obj_name)); + break; + } + } + + pos += match.capturedLength(); + } + } + while(pos >= 0); +} + +void PgModelerCliApp::fixModel() +{ + printMessage(tr("Starting model fixing...")); + printMessage(tr("Loading input file: %1").arg(parsed_opts[Input])); + printMessage(tr("Fixed model file: %1").arg(parsed_opts[Output])); + + QString fix_log = GlobalAttributes::getTemporaryFilePath(ModelFixLog); + QFile::remove(fix_log); + extractObjectXML(); + recreateObjects(); + + printMessage(tr("Updating relationships...")); + + // Forcing a full relationship revalidation so the special objects can be created properly + if(model->getObjectCount(ObjectType::Relationship) > 0) + { + model->storeSpecialObjectsXML(); + model->disconnectRelationships(); + model->validateRelationships(); + } + + model->updateTablesFKRelationships(); + + printMessage(tr("Saving fixed output model...")); + model->saveModel(parsed_opts[Output], SchemaParser::XmlCode); + + if(!has_fix_log) + printMessage(tr("Model successfully fixed!")); + else + { + printMessage(tr("Model fixed with some errors!")); + printMessage(tr("Failures registered in log file: %1").arg(fix_log)); + } +} + +void PgModelerCliApp::loadModel() +{ + //Create the systems objects on model before loading it + model->createSystemObjects(false); + + //Load the model file + model->loadModel(parsed_opts[Input]); + + /* The scene object is created only when some options are used + * so we need to check it if is not null to avoid segfaults */ + if(scene) + { + scene->blockSignals(true); + + scene->addLayers(model->getLayers(), false); + scene->setActiveLayers(model->getActiveLayers()); + scene->setLayerColors(ObjectsScene::LayerNameColor, model->getLayerNameColors()); + scene->setLayerColors(ObjectsScene::LayerRectColor, model->getLayerRectColors()); + scene->setLayerNamesVisible(model->isLayerNamesVisible()); + scene->setLayerRectsVisible(model->isLayerRectsVisible()); + model->setObjectsModified({ ObjectType::Schema }); + + scene->blockSignals(false); + } +} + +void PgModelerCliApp::exportModel() +{ + printMessage(tr("Starting model export...")); + printMessage(tr("Loading input file: %1").arg(parsed_opts[Input])); + + loadModel(); + + //Export to PNG + if(parsed_opts.count(ExportToPng)) + { + printMessage(tr("Export to PNG image: %1").arg(parsed_opts[Output])); + + export_hlp->exportToPNG(scene, parsed_opts[Output], zoom, + parsed_opts.count(ShowGrid) > 0, + parsed_opts.count(ShowDelimiters) > 0, + parsed_opts.count(PageByPage) > 0); + } + //Export to SVG + else if(parsed_opts.count(ExportToSvg)) + { + printMessage(tr("Export to SVG file: %1").arg(parsed_opts[Output])); + + export_hlp->exportToSVG(scene, parsed_opts[Output], + parsed_opts.count(ShowGrid) > 0, + parsed_opts.count(ShowDelimiters) > 0); + } + //Export to SQL file + else if(parsed_opts.count(ExportToFile)) + { + DatabaseModel::CodeGenMode code_gen_option = DatabaseModel::OriginalSql; + + if(parsed_opts.count(DependenciesSql)) + code_gen_option = DatabaseModel::DependenciesSql; + else if(parsed_opts.count(ChildrenSql)) + code_gen_option = DatabaseModel::ChildrenSql; + + if(!parsed_opts.count(Split)) + printMessage(tr("Export to SQL script file: %1").arg(parsed_opts[Output])); + else + printMessage(tr("Export to output directory: %1").arg(parsed_opts[Output])); + + export_hlp->exportToSQL(model, parsed_opts[Output], parsed_opts[PgSqlVer], + parsed_opts.count(Split) > 0, code_gen_option); + } + //Export data dictionary + else if(parsed_opts.count(ExportToDict)) + { + printMessage(tr("Export to data dictionary: %1").arg(parsed_opts[Output])); + export_hlp->exportToDataDict(model, parsed_opts[Output], + parsed_opts.count(NoIndex) == 0, + parsed_opts.count(Split) > 0); + } + //Export to DBMS + else + { + printMessage(tr("Export to DBMS: %1").arg(connection.getConnectionString().replace(PasswordRegExp, PasswordPlaceholder))); + + if(parsed_opts.count(IgnoreErrorCodes)) + export_hlp->setIgnoredErrors(parsed_opts[IgnoreErrorCodes].split(',')); + + export_hlp->exportToDBMS(model, connection, parsed_opts[PgSqlVer], + parsed_opts.count(IgnoreDuplicates) > 0, + parsed_opts.count(DropDatabase) > 0, + parsed_opts.count(DropObjects) > 0, + parsed_opts.count(Simulate) > 0, + parsed_opts.count(UseTmpNames) > 0); + } + + printMessage(tr("Export successfully ended!\n")); +} + +void PgModelerCliApp::importDatabase() +{ + printMessage(tr("Starting database import...")); + printMessage(tr("Input database: %1").arg(connection.getConnectionId(true, true))); + + ModelWidget *model_wgt = new ModelWidget; + + importDatabase(model_wgt->getDatabaseModel(), connection); + model_wgt->rearrangeSchemasInGrid(); + + printMessage(tr("Saving the imported database to file...")); + + model_wgt->getDatabaseModel()->saveModel(parsed_opts[Output], SchemaParser::XmlCode); + + printMessage(tr("Import successfully ended!\n")); + + delete model_wgt; +} + +void PgModelerCliApp::importDatabase(DatabaseModel *model, Connection conn) +{ + try + { + std::map> obj_oids; + std::map> col_oids; + Catalog catalog; + QString db_oid; + QStringList force_tab_objs; + bool imp_sys_objs = (parsed_opts.count(ImportSystemObjs) > 0), + imp_ext_objs = (parsed_opts.count(ImportExtensionObjs) > 0); + + if(parsed_opts[ForceChildren] == AllChildren) + { + for(auto &type : BaseObject::getChildObjectTypes(ObjectType::Table)) + { + if(type == ObjectType::Column) + continue; + + force_tab_objs.append(BaseObject::getSchemaName(type)); + } + } + else + force_tab_objs = parsed_opts[ForceChildren].split(',', Qt::SkipEmptyParts); + + Connection::setPrintSQL(parsed_opts.count(DebugMode) > 0); + + catalog.setConnection(conn); + + catalog.setQueryFilter(Catalog::ListAllObjects | Catalog::ExclBuiltinArrayTypes | + Catalog::ExclExtensionObjs | Catalog::ExclSystemObjs); + + catalog.setObjectFilters(obj_filters, parsed_opts.count(OnlyMatching) > 0, + parsed_opts.count(MatchByName) == 0, force_tab_objs); + + catalog.getObjectsOIDs(obj_oids, col_oids, {{Attributes::FilterTableTypes, Attributes::True}}); + + db_oid = catalog.getObjectOID(conn.getConnectionParam(Connection::ParamDbName), ObjectType::Database); + obj_oids[ObjectType::Database].push_back(db_oid.toUInt()); + catalog.closeConnection(); + + import_hlp->setConnection(conn); + import_hlp->setImportOptions(imp_sys_objs, + imp_ext_objs, + true, + parsed_opts.count(IgnoreImportErrors) > 0, + parsed_opts.count(DebugMode) > 0, + !parsed_opts.count(Diff), + !parsed_opts.count(Diff), + parsed_opts.count(CommentsAsAliases) > 0); + + model->createSystemObjects(true); + import_hlp->setSelectedOIDs(model, obj_oids, col_oids); + import_hlp->importDatabase(); + import_hlp->closeConnection(); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} + +void PgModelerCliApp::diffModelDatabase() +{ + DatabaseModel *model_aux = new DatabaseModel(); + QString dbname; + std::vector filtered_objs; + + printMessage(tr("Starting diff process...")); + + if(!parsed_opts[Input].isEmpty()) + printMessage(tr("Input model: %1").arg(parsed_opts[Input])); + else + printMessage(tr("Input database: %1").arg(connection.getConnectionId(true, true))); + + dbname = extra_connection.getConnectionId(true, true); + printMessage(tr("Compare to: %1").arg(dbname)); + + if(!parsed_opts[Input].isEmpty()) + { + printMessage(tr("Loading input model...")); + loadModel(); + + if(parsed_opts.count(PartialDiff)) + { + QString search_attr = parsed_opts.count(MatchByName) ? Attributes::Name : Attributes::Signature; + + // Filtering by modification date always forces the signature matching + if(start_date.isValid() || end_date.isValid()) + obj_filters.append(model->getFiltersFromChangelog(start_date, end_date)); + + filtered_objs = model->findObjects(obj_filters, search_attr); + + /* We need to finish the diff if no object was found based on the filters + * this will avoid the diff between an empty database model and a full database model + * which may produce unexpected results like try to recreate all objects from the database + * model that contains objects */ + if(filtered_objs.empty()) + { + printMessage(tr("No object was retrieved using the provided filter(s).")); + + if(!parsed_opts.count(Force)) + { + printMessage(tr("Use the option `%1' to force a full diff in this case.").arg(Force)); + printMessage(tr("The diff process will not continue!\n")); + return; + } + else + printMessage(tr("Switching to full diff...")); + } + else + { + /* Special case: when performing a partial diff between a model and a database + * and in the set of filtered model objects we have one or more many-to-many, inheritance or partitioning + * relationships we need to inject filters to force the retrieval of the all involved tables in those relationships + * from the destination database,this way we avoid the diff try to create everytime all tables + * in the those relationships. */ + obj_filters.append(ModelsDiffHelper::getRelationshipFilters(filtered_objs, search_attr == Attributes::Signature)); + } + } + } + else + { + printMessage(tr("Importing the database `%1'...").arg(connection.getConnectionId(true, true))); + importDatabase(model, connection); + } + + printMessage(tr("Importing the database `%1'...").arg(dbname)); + importDatabase(model_aux, extra_connection); + + diff_hlp->setModels(model, model_aux); + diff_hlp->setFilteredObjects(filtered_objs); + diff_hlp->setDiffOption(ModelsDiffHelper::OptKeepClusterObjs, !parsed_opts.count(DropClusterObjs)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptCascadeMode, !parsed_opts.count(NoCascadeDrop)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptForceRecreation, parsed_opts.count(ForceRecreateObjs)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptRecreateUnmodifiable, parsed_opts.count(OnlyUnmodifiable)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptKeepObjectPerms, !parsed_opts.count(RevokePermissions)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptReuseSequences, !parsed_opts.count(NoSequenceReuse)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptPreserveDbName, !parsed_opts.count(RenameDb)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptDontDropMissingObjs, !parsed_opts.count(DropMissingObjs)); + diff_hlp->setDiffOption(ModelsDiffHelper::OptDropMissingColsConstr, !parsed_opts.count(ForceDropColsConstrs)); + + if(!parsed_opts[PgSqlVer].isEmpty()) + diff_hlp->setPgSQLVersion(parsed_opts[PgSqlVer]); + else + { + extra_connection.connect(); + diff_hlp->setPgSQLVersion(extra_connection.getPgSQLVersion(true)); + extra_connection.close(); + } + + printMessage(tr("Comparing the generated models...")); + diff_hlp->diffModels(); + + if(diff_hlp->getDiffDefinition().isEmpty()) + printMessage(tr("No differences were detected.")); + else + { + if(parsed_opts.count(SaveDiff)) + { + printMessage(tr("Saving diff to file `%1'").arg(parsed_opts[Output])); + UtilsNs::saveFile(parsed_opts[Output], diff_hlp->getDiffDefinition().toUtf8()); + } + else + { + bool apply_diff = true; + + if(!parsed_opts.count(NoDiffPreview)) + { + QString res, buff, line; + QTextStream in(stdin), preview; + + buff += "\n** Press ENTER to scroll the preview **\n"; + buff += "\n### DIFF PREVIEW ###\n\n"; + buff += diff_hlp->getDiffDefinition(); + buff += "\n### END OF PREVIEW ###\n\n"; + + preview.setString(&buff, QIODevice::ReadOnly); + + while(!preview.atEnd()) + { + line = preview.readLine(); + res.append(line + '\n'); + + if(res.count(QChar('\n')) >= 30 || preview.atEnd()) + { + out << res; + out.flush(); + res.clear(); + + if(!preview.atEnd()) + in.readLine(); + } + } + + out << Qt::endl; + out << tr("** WARNING: You are about to apply the generated diff code to the server. Some data can be lost in the process!") << Qt::endl; + + do + { + out << tr("** Proceed with the diff applying? (yes/no) > "); + out.flush(); + + in.skipWhiteSpace(); + res = in.readLine(); + } + while(res.toLower() != tr("yes") && res.toLower() != tr("no")); + + if(res.toLower() == tr("no")) + { + apply_diff = false; + printMessage(tr("Diff code not applied to the server.")); + } + } + + if(apply_diff) + { + printMessage(tr("Applying diff to the database `%1'...").arg(dbname)); + export_hlp->setExportToDBMSParams(diff_hlp->getDiffDefinition(), + &extra_connection, + parsed_opts[CompareTo], parsed_opts.count(IgnoreDuplicates)); + + if(parsed_opts.count(IgnoreErrorCodes)) + export_hlp->setIgnoredErrors(parsed_opts[IgnoreErrorCodes].split(',')); + + export_hlp->exportToDBMS(); + } + } + } + + printMessage(tr("Diff successfully ended!\n")); +} + +void PgModelerCliApp::updateMimeType() +{ +#ifndef Q_OS_MAC + try + { + printMessage(tr("Starting mime update...")); + + handleMimeDatabase(parsed_opts[DbmMimeType]==Uninstall, parsed_opts.count(SystemWide) != 0, parsed_opts.count(Force) != 0); + + printMessage(tr("Mime database successfully updated!\n")); + } + catch (Exception &e) + { + throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } +#endif +} + +QStringList PgModelerCliApp::extractForeignKeys(QString &obj_xml) +{ + QStringList constr_lst; + int start=0, end=0, pos=0, count=0; + QString start_tag=QString("<%1").arg(Attributes::Constraint), + end_tag=QString(" 0 && end > 0) + { + count=(end - start) + end_tag.size() + 1; + constr=obj_xml.mid(start, count); + + if(constr.contains(Attributes::FkConstr)) + { + obj_xml.remove(start, count); + constr_lst.push_back(constr); + pos=0; + } + else + pos=end; + } + else + break; + } + while(pos >= 0 && pos < obj_xml.size()); + + return constr_lst; +} + +bool PgModelerCliApp::containsRelAttributes(const QString &str) +{ + bool found=false; + static std::vector attribs={ Attributes::Relationship, + Attributes::Type, Attributes::SrcRequired, Attributes::DstRequired, + Attributes::SrcTable, Attributes::DstTable, Attributes::Points, + Attributes::Columns, Attributes::Column, Attributes::Constraint, + Attributes::Label, Attributes::Line, Attributes::Position, + Attributes::Identifier, Attributes::Deferrable, Attributes::DeferType, + Attributes::TableName, Attributes::SpecialPkCols, Attributes::Table, + Attributes::AncestorTable, Attributes::CopyOptions, Attributes::CopyMode, + Attributes::SrcColPattern, Attributes::DstColPattern, Attributes::PkPattern, + Attributes::UqPattern, Attributes::SrcFkPattern, Attributes::DstFkPattern }; + + for(unsigned i=0; i < attribs.size() && !found; i++) + found=str.contains(attribs[i]); + + return found; +} + +void PgModelerCliApp::handleMimeDatabase(bool uninstall, bool system_wide, bool force) +{ + printMessage(tr("Mime database operation: %1").arg(uninstall ? "uninstall" : "install")); + + #ifdef Q_OS_LINUX + handleLinuxMimeDatabase(uninstall, system_wide, force); + #else + #ifdef Q_OS_WIN + handleWindowsMimeDatabase(uninstall, system_wide, force); + #endif + #endif +} + +void PgModelerCliApp::handleLinuxMimeDatabase(bool uninstall, bool system_wide, bool force) +{ + SchemaParser schparser; + attribs_map attribs; + QString str_aux, + + share_path = !system_wide ? QDir::homePath() + "/.local/share" : "/usr/share", + + //Configures the path to the application logo + exec_icon=GlobalAttributes::getTmplConfigurationFilePath("", "pgmodeler_logo.png"), + + //Configures the path to the document logo + dbm_icon=GlobalAttributes::getTmplConfigurationFilePath("", "pgmodeler_dbm.png"), + + sch_icon=GlobalAttributes::getTmplConfigurationFilePath("", "pgmodeler_sch.png"), + + //Path to directory that register mime types + mime_db_dir=QString("%1/mime").arg(share_path), + + //Path to the file that associates apps to mimetypes + mimeapps=QString("%1/applications/mimeapps.list").arg(share_path); + + //Files generated after update file association (application-dbm.xml and pgModeler.desktop) + QStringList files = { QString("%1/applications/pgModeler.desktop").arg(share_path), + QString("%1/applications/pgModelerSchEditor.desktop").arg(share_path), + mime_db_dir + "/packages/application-dbm.xml", + mime_db_dir + "/packages/application-sch.xml"}, + + schemas = { GlobalAttributes::getTmplConfigurationFilePath(GlobalAttributes::SchemasDir, "desktop" + GlobalAttributes::SchemaExt), + GlobalAttributes::getTmplConfigurationFilePath(GlobalAttributes::SchemasDir, "desktop-sch" + GlobalAttributes::SchemaExt), + GlobalAttributes::getTmplConfigurationFilePath(GlobalAttributes::SchemasDir, "application-dbm" + GlobalAttributes::SchemaExt), + GlobalAttributes::getTmplConfigurationFilePath(GlobalAttributes::SchemasDir, "application-sch" + GlobalAttributes::SchemaExt) }, + + icons = { exec_icon, sch_icon, dbm_icon, sch_icon }; + + QByteArray buf, buf_aux; + QFile out; + + for(unsigned i=0; i < 4; i++) + { + //When installing, check if the necessary file exists. If exists, raises an error and abort. + if(!uninstall && QFileInfo(files[i]).exists() && !force) + throw Exception(MsgFileAssociated, ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(uninstall && !QFileInfo(files[i]).exists() && !force) + throw Exception(MsgNoFileAssociation, ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + if(!uninstall && !system_wide) + attribs[Attributes::WorkingDir]=QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + else + attribs[Attributes::WorkingDir]=""; + + try + { + for(unsigned i=0; i < 4; i++) + { + if(uninstall) + { + if(!QFile(files[i]).remove() && !force) + { + throw Exception(tr("Can't erase the file %1! Check if the current user has permissions to delete it and if the file exists.").arg(files[i]), + ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + else + { + attribs[Attributes::Application]=(i == 0 ? GlobalAttributes::getPgModelerAppPath() : GlobalAttributes::getPgModelerSchemaEditorPath()); + attribs[Attributes::Icon] = icons[i]; + + schparser.loadFile(schemas[i]); + schparser.ignoreEmptyAttributes(true); + buf.append(schparser.getSourceCode(attribs).toUtf8()); + QDir(".").mkpath(QFileInfo(files[i]).absolutePath()); + + UtilsNs::saveFile(files[i], buf); + buf.clear(); + } + } + + out.setFileName(mimeapps); + + //If the file mimeapps.list doesn't exists (generally in Ubuntu) creates a new one + if(!uninstall && !QFileInfo(mimeapps).exists()) + { + out.open(QFile::WriteOnly); + out.write(QByteArray("[Added Associations]\napplication/dbm=pgModeler.desktop;\n")); + out.write(QByteArray("\n[Default Applications]\napplication/dbm=pgModeler.desktop;\n")); + out.write(QByteArray("\n[Added Associations]\napplication/sch=pgModelerStxEditor.desktop;\n")); + out.write(QByteArray("\n[Default Applications]\napplication/sch=pgModelerStxEditor.desktop;\n")); + out.close(); + } + else + { + out.open(QFile::ReadOnly); + + if(!out.isOpen()) + throw Exception(Exception::getErrorMessage(ErrorCode::FileDirectoryNotWritten).arg(mimeapps), + ErrorCode::FileDirectoryNotWritten,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Opens the mimeapps.list to add a entry linking pgModeler to .dbm files + buf=out.readAll(); + out.close(); + + QTextStream ts(&buf); + while(!ts.atEnd()) + { + //Remove any reference to application/dbm mime from file + str_aux=ts.readLine(); + str_aux.replace(QRegularExpression(QRegularExpression::wildcardToRegularExpression("application/dbm*")),""); + + if(!str_aux.isEmpty()) + { + //Updates the application/dbm mime association + if(!uninstall && (str_aux.contains("[Added Associations]") || + str_aux.contains("[Default Applications]"))) + str_aux.append("\napplication/dbm=pgModeler.desktop;\n"); + else + str_aux+="\n"; + + if(str_aux.startsWith("[") && !str_aux.contains("Added Associations")) + str_aux="\n" + str_aux; + + buf_aux.append(str_aux.toUtf8()); + } + } + + //Write a new copy of the mimeapps.list file + out.open(QFile::Truncate | QFile::WriteOnly); + out.write(buf_aux.data(), buf_aux.size()); + out.close(); + } + + //Update the mime database + printMessage(tr("Running update-mime-database command...")); + + QProcess::execute("update-mime-database", QStringList { mime_db_dir }); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } +} + +void PgModelerCliApp::handleWindowsMimeDatabase(bool uninstall, bool system_wide, bool force) +{ + SchemaParser schparser; + QString base_reg_key = system_wide ? "HKEY_LOCAL_MACHINE\\SOFTWARE" : "HKEY_CURRENT_USER\\Software"; + + //Checking if the .dbm registry key exists + QSettings dbm_ext(QString("%1\\Classes\\%2").arg(base_reg_key, GlobalAttributes::DbModelExt), QSettings::NativeFormat), + sch_ext(QString("%1\\Classes\\.sch").arg(base_reg_key), QSettings::NativeFormat); + QString exe_path=QDir::toNativeSeparators(GlobalAttributes::getPgModelerAppPath()), + sc_exe_path=QDir::toNativeSeparators(GlobalAttributes::getPgModelerSchemaEditorPath()); + + //If there is no value assigned to (.dbm | .sch)/Default key and the user wants to uninstall file association, raises an error + if(uninstall && !force && + (dbm_ext.value("Default").toString().isEmpty() || + sch_ext.value("Default").toString().isEmpty())) + throw Exception(MsgNoFileAssociation, ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!uninstall && !force && + (!dbm_ext.value("Default").toString().isEmpty() || + !sch_ext.value("Default").toString().isEmpty())) + throw Exception(MsgFileAssociated, ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + if(!uninstall) + { + //Write the default value for .dbm registry key + dbm_ext.setValue("Default", "dbm_auto_file"); + sch_ext.setValue("Default", "sch_auto_file"); + } + else + { + dbm_ext.remove(""); + sch_ext.remove(""); + } + + dbm_ext.sync(); + sch_ext.sync(); + + //Other registry keys values + std::map confs = { + { QString("\\%1\\Classes\\dbm_auto_file").arg(base_reg_key), { "FriendlyTypeName" , "pgModeler Database Model" } }, + { QString("\\%1\\Classes\\dbm_auto_file\\DefaultIcon").arg(base_reg_key), { "Default" , QString("%1,1").arg(exe_path) } }, + { QString("\\%1\\Classes\\dbm_auto_file\\shell\\open\\command").arg(base_reg_key), { "Default", QString("\"%1\" \"%2\"").arg(exe_path).arg("%1") } }, + { QString("\\%1\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\%2").arg(base_reg_key, GlobalAttributes::DbModelExt), { "OpenWithList/a", "pgmodeler.exe", "OpenWithList/MRUList", "a"} }, + { QString("\\%1\\Classes\\sch_auto_file").arg(base_reg_key), { "FriendlyTypeName" , "pgModeler Schema File" } }, + { QString("\\%1\\Classes\\sch_auto_file\\DefaultIcon").arg(base_reg_key), { "Default" , QString("%1,1").arg(sc_exe_path) } }, + { QString("\\%1\\Classes\\sch_auto_file\\shell\\open\\command").arg(base_reg_key), { "Default" , QString("\"%1\" \"%2\"").arg(sc_exe_path).arg("%1") } }, + { QString("\\%1\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.sch").arg(base_reg_key), { "OpenWithList/a", "pgmodeler-sc.exe", "OpenWithList/MRUList", "a"} } + }; + + std::map::iterator itr; + itr=confs.begin(); + + //Iterates over the configuration map writing the other keys on registry + while(itr!=confs.end()) + { + QSettings s(itr->first, QSettings::NativeFormat); + + if(uninstall) + s.remove(""); + else + { + for(int i=0; i < itr->second.size(); i+=2) + s.setValue(itr->second[i], itr->second[i+1]); + } + + s.sync(); + itr++; + } +} + +void PgModelerCliApp::createConfigurations() +{ + QString conf_dir = GlobalAttributes::getConfigurationsPath(); + + printMessage(tr("Creating configuration files...")); + printMessage(tr("Destination path: %1").arg(conf_dir)); + + bool missing_only = parsed_opts.count(MissingOnly) > 0, + force = parsed_opts.count(Force) > 0; + + if(!missing_only && !force && QDir(GlobalAttributes::getConfigurationsPath()).exists()) + throw Exception(tr("Configuration files already exist!"), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + try + { + if(force) + { + QDir dir; + QString bkp_conf_dir = conf_dir + QDateTime::currentDateTime().toString("_yyyyMMdd_hhmmss"); + + printMessage(tr("Configuration files already exist! Creating a backup...")); + printMessage(tr("Backup path: %1").arg(bkp_conf_dir)); + + if(!dir.rename(conf_dir, bkp_conf_dir)) + throw Exception(tr("Failed to create the configuration files backup!").arg(bkp_conf_dir), ErrorCode::Custom,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + createUserConfiguration(missing_only); + printMessage(tr("Configuration files successfully created!\n")); + } + catch (Exception &e) + { + throw Exception(e.getErrorMessage(),e.getErrorCode(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } +} diff --git a/apps/pgmodeler-cli/src/pgmodelercliapp.h b/apps/pgmodeler-cli/src/pgmodelercliapp.h new file mode 100644 index 0000000000..2988ccafa8 --- /dev/null +++ b/apps/pgmodeler-cli/src/pgmodelercliapp.h @@ -0,0 +1,284 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup pgmodeler-cli +\class PgModelerCliApp +\brief Implements the operations export models whitout use the graphical interface +*/ + +#ifndef PGMODELER_CLI_APP_H +#define PGMODELER_CLI_APP_H + +#include "application.h" +#include +#include +#include +#include "tools/modelexporthelper.h" +#include "settings/generalconfigwidget.h" +#include "settings/connectionsconfigwidget.h" +#include "settings/relationshipconfigwidget.h" +#include "settings/generalconfigwidget.h" +#include "tools/databaseimporthelper.h" +#include "tools/modelsdiffhelper.h" + +class PgModelerCliApp: public Application { + private: + Q_OBJECT + + XmlParser *xmlparser; + + qint64 buffer_size; + + bool has_fix_log; + + //! \brief Holds the pgModeler version in which the model was construted (used by the fix operation) + QString model_version; + + //! \brief Export helper object + ModelExportHelper *export_hlp; + + //! \brief Import helper object + DatabaseImportHelper *import_hlp; + + //! \brief Diff helper object + ModelsDiffHelper *diff_hlp; + + //! \brief Reference database model + DatabaseModel *model; + + //! \brief Graphical scene used to export the model to png + ObjectsScene *scene; + + //! \brief Stores the configured connection + Connection connection, + + //! \brief Stores the extra configured connection (only for diff) + extra_connection; + + //! \brief Loaded connections + std::map connections; + + //! \brief Connection configuration widget used to load available connections from file + ConnectionsConfigWidget *conn_conf; + + //! \brief Relationship configuration widget used to load custom relationship settings + RelationshipConfigWidget *rel_conf; + + GeneralConfigWidget *general_conf; + + //! \brief Creates an standard out to handles QStrings + static QTextStream out; + + //! \brief Stores the long option names. The boolean indicates if the option accepts a value + static std::map long_opts; + + //! \brief Stores the short option names. + static attribs_map short_opts; + + //! \brief Stores the accepted options by the different operations + static std::map accepted_opts; + + //! \brief Stores the parsed options names and values. + attribs_map parsed_opts; + + //! \brief Indicates if the cli must run in silent mode + bool silent_mode; + + //! \brief Stores the xml code for the objects being fixed + QStringList objs_xml, + + //! \brief Stores the object filters for reverse engineering + obj_filters; + + //! \brief Zoom to be applied onto the png export + double zoom; + + //! \brief Start date used for filter changelog of the input database model (partial diff) + QDateTime start_date, + + //! \brief End date used for filter changelog of the input database model (partial diff) + end_date; + + /*! \brief Stores the member of role names that appear in deprecated tags + * This map is used to reconfigure the role memberships after all objects are created */ + std::map member_roles; + + //! \brief Stores the changelog of the model that is being fixed to reproduce it in the output model + QString changelog; + + static const QRegularExpression PasswordRegExp; + static const QString PasswordPlaceholder; + + //! \brief Option names constants + static const QString Input, + Output, + InputDb, + ExportToFile, + ExportToPng, + ExportToSvg, + ExportToDbms, + ExportToDict, + ImportDb, + Diff, + DropDatabase, + DropObjects, + PgSqlVer, + Help, + ShowGrid, + ShowDelimiters, + PageByPage, + IgnoreDuplicates, + IgnoreErrorCodes, + ConnAlias, + Host, + Port, + User, + Passwd, + InitialDb, + Silent, + ListConns, + Simulate, + FixModel, + FixTries, + ZoomFactor, + UseTmpNames, + DbmMimeType, + Install, + Uninstall, + SystemWide, + NoIndex, + Split, + OriginalSql, + DependenciesSql, + ChildrenSql, + + IgnoreImportErrors, + ImportSystemObjs, + ImportExtensionObjs, + DebugMode, + FilterObjects, + OnlyMatching, + MatchByName, + ForceChildren, + AllChildren, + CommentsAsAliases, + + PartialDiff, + Force, + StartDate, + EndDate, + CompareTo, + SaveDiff, + ApplyDiff, + NoDiffPreview, + DropClusterObjs, + RevokePermissions, + DropMissingObjs, + ForceDropColsConstrs, + RenameDb, + NoSequenceReuse, + NoCascadeDrop, + ForceRecreateObjs, + OnlyUnmodifiable, + + CreateConfigs, + MissingOnly, + + TagExpr, + EndTagExpr, + AttributeExpr, + + MsgFileAssociated, + MsgNoFileAssociation, + ModelFixLog; + + //! \brief Parsers the options and executes the action specified by them + void parseOptions(attribs_map &parsed_opts); + + //! \brief Shows the options menu + void showMenu(); + + //! \brief Shows the version info + void showVersionInfo(); + + //! \brief Returns if the specified options exists on short options map + bool isOptionRecognized(QString &op, bool &accepts_val); + + //! \brief Loads the input model and perform all tasks needed to configure the graphical objects + void loadModel(); + + /*! \brief Extracts the xml defintions from the input model and store them on obj_xml list + in order to be parsed by the recreateObjects() method */ + void extractObjectXML(); + + //! \brief Recreates the objects from the obj_xml list fixing the creation order for them + void recreateObjects(); + + //! \brief Fix some xml attributes and remove unused tags + void fixObjectAttributes(QString &obj_xml); + + /*! \brief Extracts the foreign key code for the specified table xml. The foreign keys + are recreated after all the other objects */ + QStringList extractForeignKeys(QString &obj_xml); + + //! \brief Returns if the specified string contains some of relationship attributes + bool containsRelAttributes(const QString &str); + + /*! \brief Install the .dbm file association in the mime database (default behaviour). + The paramenter 'uninstall' is used to clean up any file association done previously. */ + void handleMimeDatabase(bool uninstall, bool system_wide, bool force); + + /*! \brief Fixes the references to opertor classes and families by replacing tags like + by . This method operates + only over operator classes, indexes and constraints */ + void fixOpClassesFamiliesReferences(QString &obj_xml); + + void fixModel(); + void exportModel(); + void importDatabase(); + void diffModelDatabase(); + void updateMimeType(); + void configureConnection(bool extra_conn); + void importDatabase(DatabaseModel *model, Connection conn); + + /*! \brief Prints to the stdout the provided text appending a \n on the string + * even if the silent mode is active. */ + void printText(const QString &txt = ""); + + //! \brief Prints to the stdout only if the silent mode is not active + void printMessage(const QString &txt = ""); + + void handleLinuxMimeDatabase(bool uninstall, bool system_wide, bool force); + void handleWindowsMimeDatabase(bool uninstall, bool system_wide, bool force); + void createConfigurations(); + void listConnections(); + + public: + PgModelerCliApp(int argc, char **argv); + virtual ~PgModelerCliApp(); + int exec(); + + private slots: + void handleObjectAddition(BaseObject *); + void updateProgress(int progress, QString msg, ObjectType = ObjectType::BaseObject); + void printIgnoredError(QString err_cod, QString err_msg, QString cmd); + void handleObjectRemoval(BaseObject *object); +}; + +#endif diff --git a/apps/pgmodeler-se/pgmodeler-se.pro b/apps/pgmodeler-se/pgmodeler-se.pro new file mode 100644 index 0000000000..e9ed04f59f --- /dev/null +++ b/apps/pgmodeler-se/pgmodeler-se.pro @@ -0,0 +1,34 @@ +include(../apps.pri) + +TEMPLATE = app +TARGET = pgmodeler-se + +windows:RC_FILE=res/windows_ico.qrc +windows:RCC_DIR=src/ + +SOURCES += src/main.cpp \ + src/aboutsewidget.cpp \ + src/schemaeditorform.cpp \ + src/sourceeditorwidget.cpp \ + ../pgmodeler/src/pgmodelerapp.cpp \ + +FORMS += \ + ui/aboutsewidget.ui \ + ui/schemaeditorform.ui \ + ui/sourceeditorwidget.ui + +HEADERS += \ + src/aboutsewidget.h \ + src/schemaeditorform.h \ + src/sourceeditorwidget.h + +INCLUDEPATH += ../pgmodeler/src + +DEPENDPATH += ../pgmodeler + +# Deployment settings +target.path = $$PRIVATEBINDIR +INSTALLS = target + +# Print the current build settins (see pgmodeler.pri) +printBuildDetails() diff --git a/apps/pgmodeler-se/res/windows_ico.ico b/apps/pgmodeler-se/res/windows_ico.ico new file mode 100644 index 0000000000..0c159bded8 Binary files /dev/null and b/apps/pgmodeler-se/res/windows_ico.ico differ diff --git a/apps/pgmodeler-se/res/windows_ico.qrc b/apps/pgmodeler-se/res/windows_ico.qrc new file mode 100644 index 0000000000..33cce51734 --- /dev/null +++ b/apps/pgmodeler-se/res/windows_ico.qrc @@ -0,0 +1 @@ + IDI_ICON1 ICON DISCARDABLE "windows_ico.ico" \ No newline at end of file diff --git a/apps/pgmodeler-se/src/aboutsewidget.cpp b/apps/pgmodeler-se/src/aboutsewidget.cpp new file mode 100644 index 0000000000..f53700aac5 --- /dev/null +++ b/apps/pgmodeler-se/src/aboutsewidget.cpp @@ -0,0 +1,32 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "aboutsewidget.h" +#include "guiutilsns.h" + +AboutSEWidget::AboutSEWidget(QWidget *parent) : QWidget(parent) +{ + setupUi(this); + + GuiUtilsNs::configureWidgetFont(title_lbl, GuiUtilsNs::HugeFontFactor); + GuiUtilsNs::configureWidgetFont(pgmodeler_ver_lbl, GuiUtilsNs::HugeFontFactor); + GuiUtilsNs::configureWidgetFont(build_num_lbl, GuiUtilsNs::BigFontFactor); + + pgmodeler_ver_lbl->setText(QString("v%1 ").arg(GlobalAttributes::PgModelerVersion)); + build_num_lbl->setText(QString("%1 Qt %2").arg(GlobalAttributes::PgModelerBuildNumber).arg(QT_VERSION_STR)); +} diff --git a/apps/pgmodeler-se/src/aboutsewidget.h b/apps/pgmodeler-se/src/aboutsewidget.h new file mode 100644 index 0000000000..038cdc3a1c --- /dev/null +++ b/apps/pgmodeler-se/src/aboutsewidget.h @@ -0,0 +1,39 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup pgmodeler-se +\class AboutSEWidget +\brief Form that contains information about software authoring and licensing. +*/ + +#ifndef ABOUT_SE_WIDGET_H +#define ABOUT_SE_WIDGET_H + +#include +#include "ui_aboutsewidget.h" + +class AboutSEWidget: public QWidget, public Ui::AboutSEWidget { + private: + Q_OBJECT + + public: + AboutSEWidget(QWidget *parent = nullptr); +}; + +#endif diff --git a/apps/pgmodeler-se/src/main.cpp b/apps/pgmodeler-se/src/main.cpp new file mode 100644 index 0000000000..a258df6426 --- /dev/null +++ b/apps/pgmodeler-se/src/main.cpp @@ -0,0 +1,50 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "application.h" +#include +#include "schemaeditorform.h" +#include "pgmodelerapp.h" +#include "exception.h" +#include "enumtype.h" + +int main(int argc, char **argv) +{ + try + { + GlobalAttributes::setCustomUiScaleFactor(); + PgModelerApp app(argc,argv); + QStringList args = app.arguments(); + SchemaEditorForm syntaxchk; + + app.loadTranslation(QLocale::system().name()); + + args.pop_front(); + syntaxchk.loadFiles(args); + syntaxchk.showMaximized(); + app.exec(); + + return 0; + } + catch(Exception &e) + { + QTextStream out(stdout); + out << e.getExceptionsText(); + return enum_t(e.getErrorCode()); + } +} diff --git a/apps/pgmodeler-se/src/schemaeditorform.cpp b/apps/pgmodeler-se/src/schemaeditorform.cpp new file mode 100644 index 0000000000..80f7d40e67 --- /dev/null +++ b/apps/pgmodeler-se/src/schemaeditorform.cpp @@ -0,0 +1,563 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "schemaeditorform.h" +#include "guiutilsns.h" +#include "globalattributes.h" +#include "settings/appearanceconfigwidget.h" +#include "settings/generalconfigwidget.h" +#include "guiutilsns.h" +#include "sourceeditorwidget.h" +#include "aboutsewidget.h" +#include "baseform.h" +#include "utilsns.h" + +const QString SchemaEditorForm::UntitledFile = QT_TR_NOOP("(untitled)"); + +SchemaEditorForm::SchemaEditorForm(QWidget *parent) : QWidget(parent) +{ + QToolButton *btn = nullptr; + QFont fnt; + + setupUi(this); + setWindowTitle(windowTitle() + " " + GlobalAttributes::PgModelerVersion); + + for(auto &obj : bnts_parent_wgt->children()) + { + btn = dynamic_cast(obj); + if(!btn) continue; + + fnt = btn->font(); + fnt.setWeight(QFont::Normal); + btn->setFont(fnt); + GuiUtilsNs::createDropShadow(btn, 1, 1, 5); + + if(!btn->toolTip().isEmpty() && !btn->shortcut().toString().isEmpty()) + btn->setToolTip(btn->toolTip() + QString(" (%1)").arg(btn->shortcut().toString())); + } + + AppearanceConfigWidget appearance_conf_wgt; + appearance_conf_wgt.loadConfiguration(); + GuiUtilsNs::updateDropShadows(qApp->allWidgets()); + + GeneralConfigWidget general_conf_wgt; + general_conf_wgt.loadConfiguration(); + + alert_frm->setVisible(false); + + syntax_txt = GuiUtilsNs::createNumberedTextEditor(syntax_wgt); + syntax_hl = new SyntaxHighlighter(syntax_txt); + syntax_hl->loadConfiguration(GlobalAttributes::getXMLHighlightConfPath()); + + dtd_txt = GuiUtilsNs::createNumberedTextEditor(dtd_wgt); + dtd_txt->setReadOnly(true); + dtd_hl = new SyntaxHighlighter(dtd_txt); + dtd_hl->loadConfiguration(GlobalAttributes::getXMLHighlightConfPath()); + + SourceEditorWidget::setDefaultEditorPalette(syntax_txt->palette()); + + syntax_conf_sel = new FileSelectorWidget(syntax_conf_wgt); + syntax_conf_sel->setReadOnly(true); + + QVBoxLayout *vbox = new QVBoxLayout(syntax_conf_wgt); + vbox->addWidget(syntax_conf_sel); + vbox->setContentsMargins(0, 0, 0, 0); + + syntax_conf_sel->setNameFilters({ tr("Syntax highlight config file (*%1)").arg(GlobalAttributes::ConfigurationExt) }); + + QAction *act = nullptr; + stx_action_grp = new QActionGroup(&syntax_cfg_menu); + + act = syntax_cfg_menu.addAction("Schema file", this, &SchemaEditorForm::loadSyntaxConfig); + stx_action_grp->addAction(act); + act->setCheckable(true); + act->setChecked(true); + act->setData(GlobalAttributes::SchHighlightConf); + + act = syntax_cfg_menu.addAction("XML script", this, &SchemaEditorForm::loadSyntaxConfig); + stx_action_grp->addAction(act); + act->setCheckable(true); + act->setChecked(false); + act->setData(GlobalAttributes::XMLHighlightConf); + + act = syntax_cfg_menu.addAction("SQL script", this, &SchemaEditorForm::loadSyntaxConfig); + stx_action_grp->addAction(act); + act->setData(GlobalAttributes::SQLHighlightConf); + act->setCheckable(true); + act->setChecked(false); + + syntax_tb->setMenu(&syntax_cfg_menu); + syntax_tb->setStyleSheet("QToolButton::menu-indicator { \ +image: url(':/styles/styles/h_menu_indicator.png'); \ +subcontrol-position: right center; }"); + + syntax_cfg_menu.installEventFilter(this); + + connect(apply_conf_tb, &QToolButton::clicked, this, &SchemaEditorForm::applySyntaxConfig); + connect(save_conf_tb, &QToolButton::clicked, this, &SchemaEditorForm::saveSyntaxConfig); + connect(reload_conf_tb, &QToolButton::clicked, this, &SchemaEditorForm::loadSyntaxConfig); + + connect(new_tb, &QToolButton::clicked, this, [this](){ + addEditorTab(); + }); + + connect(load_tb, &QToolButton::clicked, this, &SchemaEditorForm::loadFile); + connect(exit_tb, &QToolButton::clicked, this, &SchemaEditorForm::close); + connect(save_tb, &QToolButton::clicked, this, &SchemaEditorForm::saveFile); + connect(indent_all_tb, &QToolButton::clicked, this, &SchemaEditorForm::indentAll); + connect(save_all_tb, &QToolButton::clicked, this, &SchemaEditorForm::saveAll); + connect(close_all_tb, &QToolButton::clicked, this, &SchemaEditorForm::closeAll); + + connect(editors_tbw, &QTabWidget::tabCloseRequested, this, [this](int idx){ + closeEditorTab(idx); + }); + + connect(editors_tbw, &QTabWidget::currentChanged, this, &SchemaEditorForm::loadSyntaxFromCurrentTab); + connect(use_tmpl_file_chk, &QCheckBox::toggled, this, &SchemaEditorForm::loadSyntaxConfig); + + connect(syntax_txt, &NumberedTextEditor::textChanged, this, [this](){ + alert_frm->setVisible(true); + }); + + connect(save_as_tb, &QToolButton::clicked, this, [this](){ + saveFile(true); + }); + + connect(about_tb, &QToolButton::clicked, this, [](){ + AboutSEWidget *info_wgt = new AboutSEWidget; + BaseForm base_frm; + base_frm.setMainWidget(info_wgt); + base_frm.exec(); + }); +} + +void SchemaEditorForm::showEvent(QShowEvent *) +{ + h_splitter->setSizes({ width(), width()/2}); +} + +bool SchemaEditorForm::hasModifiedEditors() +{ + bool editors_modified = false; + SourceEditorWidget *editor = nullptr; + + for(int tab = 0; tab < editors_tbw->count(); tab++) + { + editor = dynamic_cast(editors_tbw->widget(tab)); + + if(editor->isModified()) + { + editors_modified = true; + break; + } + } + + return editors_modified; +} + +void SchemaEditorForm::closeEvent(QCloseEvent *event) +{ + if(alert_frm->isVisible() || hasModifiedEditors()) + { + Messagebox msgbox; + + msgbox.show(tr("There are modified files! Do you want to exit without saving them?"), Messagebox::ConfirmIcon, Messagebox::YesNoButtons); + + if(msgbox.result() == QDialog::Rejected) + event->ignore(); + } +} + +bool SchemaEditorForm::eventFilter(QObject *object, QEvent *event) +{ + if(object == &syntax_cfg_menu && event->type() == QEvent::Show) + { + syntax_cfg_menu.move(mapToGlobal(syntax_tb->pos() + QPoint(syntax_tb->width(), 0))); + syntax_cfg_menu.show(); + return true; + } + + return QWidget::eventFilter(object, event); +} + +void SchemaEditorForm::loadSyntaxFromCurrentTab() +{ + SourceEditorWidget *editor = dynamic_cast(editors_tbw->currentWidget()); + + if(!editor) + return; + + stx_action_grp->blockSignals(true); + + for(auto &act : stx_action_grp->actions()) + { + if(act->data().toString() == editor->getCurrentSyntaxConfig()) + { + act->setChecked(true); + loadSyntaxConfig(); + break; + } + } + + stx_action_grp->blockSignals(true); +} + +void SchemaEditorForm::loadSyntaxConfig() +{ + QAction *act = stx_action_grp->checkedAction(); + QFile input; + QString filename; + + if(!act) + filename = GlobalAttributes::getSchHighlightConfPath(); + else + { + if(!use_tmpl_file_chk->isChecked()) + filename = GlobalAttributes::getConfigurationFilePath(act->data().toString()); + else + filename = GlobalAttributes::getTmplConfigurationFilePath("", act->data().toString() + GlobalAttributes::ConfigurationExt); + } + + try + { + syntax_txt->setPlainText(UtilsNs::loadFile(filename)); + syntax_conf_sel->setSelectedFile(filename); + + if(dtd_txt->toPlainText().isEmpty()) + { + filename = GlobalAttributes::getTmplConfigurationFilePath(GlobalAttributes::ObjectDTDDir, + GlobalAttributes::CodeHighlightConf + + GlobalAttributes::ObjectDTDExt); + + dtd_txt->setPlainText(UtilsNs::loadFile(filename)); + } + + save_conf_tb->setEnabled(true); + apply_conf_tb->setEnabled(true); + reload_conf_tb->setEnabled(true); + alert_frm->setVisible(false); + applySyntaxConfig(false); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } +} + +void SchemaEditorForm::applySyntaxConfig(bool from_temp_file) +{ + QTemporaryFile tmp_file; + QString filename; + + /* When applying the syntax on-the-fly we save the syntax conf code to a temporary file + * and use it as configuration for in the open editors */ + if(from_temp_file) + { + tmp_file.setAutoRemove(false); + tmp_file.setFileTemplate(GlobalAttributes::getTemporaryFilePath(QString("temp_XXXXXX%1").arg(GlobalAttributes::ConfigurationExt))); + tmp_file.open(); + filename = tmp_file.fileName(); + + if(!tmp_file.isOpen()) + { + throw Exception(Exception::getErrorMessage(ErrorCode::FileDirectoryNotAccessed).arg(filename), + ErrorCode::FileDirectoryNotAccessed, __PRETTY_FUNCTION__, __FILE__, __LINE__); + } + + tmp_file.write(syntax_txt->toPlainText().toUtf8()); + tmp_file.close(); + } + else if(stx_action_grp->checkedAction()) + { + if(!use_tmpl_file_chk->isChecked()) + filename = GlobalAttributes::getConfigurationFilePath(stx_action_grp->checkedAction()->data().toString()); + else + filename = GlobalAttributes::getTmplConfigurationFilePath("", stx_action_grp->checkedAction()->data().toString() + GlobalAttributes::ConfigurationExt); + } + + try + { + /* Testing the temp file contents against a dummy syntax highlighter before + * applying to the open editors */ + QPlainTextEdit dummy_txt; + SyntaxHighlighter stx_hl(&dummy_txt); + stx_hl.loadConfiguration(filename); + + SourceEditorWidget *editor = dynamic_cast(editors_tbw->currentWidget()); + + if(editor) + editor->loadSyntaxConfig(filename); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } + + if(from_temp_file) + tmp_file.remove(); +} + +void SchemaEditorForm::saveSyntaxConfig() +{ + UtilsNs::saveFile(syntax_conf_sel->getSelectedFile(), syntax_txt->toPlainText().toUtf8()); + alert_frm->setVisible(false); + applySyntaxConfig(true); +} + +void SchemaEditorForm::saveFile(bool save_as) +{ + SourceEditorWidget *editor = dynamic_cast(editors_tbw->widget(editors_tbw->currentIndex())); + QString filename = editor->getFilename(); + + if(save_as || filename.isEmpty()) + { + QStringList files = showFileDialog(true); + + if(files.isEmpty()) + return; + + filename = files.at(0); + } + + editor->saveFile(filename); + editor->setModified(false); + QFileInfo fi(filename); + editors_tbw->setTabText(editors_tbw->currentIndex(), fi.fileName()); + editors_tbw->setTabToolTip(editors_tbw->currentIndex(), fi.absoluteFilePath()); +} + +void SchemaEditorForm::setTabModified(bool modified) +{ + SourceEditorWidget *editor = dynamic_cast(sender()); + int idx = editors_tbw->indexOf(editor); + QString tab_text = editors_tbw->tabText(idx); + + if(modified && !tab_text.endsWith('*')) + tab_text += '*'; + else if(!modified) + tab_text.remove('*'); + + editors_tbw->setTabText(idx, tab_text); +} + +void SchemaEditorForm::indentAll() +{ + SourceEditorWidget *editor = nullptr; + + qApp->setOverrideCursor(Qt::WaitCursor); + + for(int tab = 0; tab < editors_tbw->count(); tab++) + { + editor = dynamic_cast(editors_tbw->widget(tab)); + editor->indent_tb->click(); + } + + qApp->restoreOverrideCursor(); +} + +void SchemaEditorForm::saveAll() +{ + qApp->setOverrideCursor(Qt::WaitCursor); + + for(int tab = 0; tab < editors_tbw->count(); tab++) + { + editors_tbw->setCurrentIndex(tab); + + try + { + saveFile(); + } + catch(Exception &e) + { + Messagebox msgbox; + msgbox.show(e); + break; + } + } + + qApp->restoreOverrideCursor(); +} + +void SchemaEditorForm::closeAll() +{ + Messagebox msgbox; + + if(hasModifiedEditors()) + { + msgbox.show(tr("There are modified files! Do you want to close them without save?"), Messagebox::ConfirmIcon, Messagebox::YesNoButtons); + + if(msgbox.result() == QDialog::Rejected) + return; + } + + qApp->setOverrideCursor(Qt::WaitCursor); + + while(editors_tbw->count() > 0) + closeEditorTab(0, false); + + qApp->restoreOverrideCursor(); +} + +QStringList SchemaEditorForm::showFileDialog(bool save_mode) +{ + QFileDialog file_dlg; + QStringList files, filters= { + tr("Schema file (*%1)").arg(GlobalAttributes::SchemaExt), + tr("Database model file (*%1)").arg(GlobalAttributes::DbModelExt), + tr("pgModeler config file (*%1)").arg(GlobalAttributes::ConfigurationExt), + tr("Objects metadata file (*%1)").arg(GlobalAttributes::ObjMetadataExt), + tr("SQL script file (*.sql)"), + tr("XML file (*.xml)"), + tr("DTD file (*.dtd)"), + tr("All files (*.*)") + }; + + if(!save_mode) + filters.prepend(tr("All supported files (*%1 *%2 *%3 *%4 *.sql *.xml *.dtd)") + .arg(GlobalAttributes::SchemaExt, GlobalAttributes::DbModelExt, + GlobalAttributes::ConfigurationExt, GlobalAttributes::ObjMetadataExt)); + + file_dlg.setNameFilters(filters); + + file_dlg.setWindowTitle(save_mode ? tr("Save file") : tr("Load file")); + file_dlg.setFileMode(save_mode ? QFileDialog::AnyFile : QFileDialog::ExistingFiles); + file_dlg.setAcceptMode(save_mode ? QFileDialog::AcceptSave : QFileDialog::AcceptOpen); + + if(save_mode) + { + file_dlg.setDefaultSuffix(".sch"); + connect(&file_dlg, &QFileDialog::filterSelected, this, [&file_dlg](QString filter){ + filter.remove(QRegularExpression("(.)+(\\*)")); + filter.remove(")"); + file_dlg.setDefaultSuffix(filter); + }); + } + + GuiUtilsNs::restoreFileDialogState(&file_dlg); + + if(file_dlg.exec() == QFileDialog::Accepted) + files = file_dlg.selectedFiles(); + + GuiUtilsNs::saveFileDialogState(&file_dlg); + + return files; +} + +void SchemaEditorForm::loadFile() +{ + try + { + QStringList files = showFileDialog(false); + + if(!files.isEmpty()) + loadFiles(files); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } +} + +void SchemaEditorForm::loadFiles(const QStringList &filenames) +{ + try + { + qApp->setOverrideCursor(Qt::WaitCursor); + + for(auto &file : filenames) + addEditorTab(file); + + qApp->restoreOverrideCursor(); + } + catch(Exception &e) + { + qApp->restoreOverrideCursor(); + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } +} + +void SchemaEditorForm::addEditorTab(const QString &filename) +{ + SourceEditorWidget *editor_wgt = nullptr; + QFileInfo fi(filename); + + try + { + editor_wgt = new SourceEditorWidget; + + if(!filename.isEmpty()) + editor_wgt->loadFile(filename); + + connect(editor_wgt, &SourceEditorWidget::s_editorModified, this, &SchemaEditorForm::setTabModified); + } + catch(Exception &e) + { + delete editor_wgt; + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } + + editors_tbw->addTab(editor_wgt, filename.isEmpty() ? UntitledFile : fi.fileName()); + editors_tbw->setTabToolTip(editors_tbw->count() - 1, filename.isEmpty() ? "" : fi.absoluteFilePath()); + editors_tbw->setCurrentIndex(editors_tbw->count() - 1); + save_as_tb->setEnabled(true); + save_tb->setEnabled(true); + indent_all_tb->setEnabled(true); + save_all_tb->setEnabled(true); + close_all_tb->setEnabled(true); + syntax_cfg_edit_frm->setEnabled(true); + syntax_tb->setEnabled(true); +} + +void SchemaEditorForm::closeEditorTab(int idx, bool confirm_close) +{ + SourceEditorWidget *editor_wgt = dynamic_cast(editors_tbw->widget(idx)); + Messagebox msgbox; + + if(editor_wgt->isModified() && confirm_close) + { + msgbox.show(tr("The source code was modified! Do you really want to close it without save?"), Messagebox::ConfirmIcon, Messagebox::YesNoButtons); + + if(msgbox.result() == QDialog::Rejected) + return; + } + + editors_tbw->removeTab(idx); + delete(editor_wgt); + + bool enable = editors_tbw->count() > 0; + save_as_tb->setEnabled(enable); + save_tb->setEnabled(enable); + indent_all_tb->setEnabled(enable); + save_all_tb->setEnabled(enable); + close_all_tb->setEnabled(enable); + syntax_cfg_edit_frm->setEnabled(enable); + syntax_tb->setEnabled(enable); + + if(!enable) + { + syntax_txt->blockSignals(true); + syntax_conf_sel->blockSignals(true); + + syntax_txt->clear(); + syntax_conf_sel->clearSelector(); + alert_frm->setVisible(false); + + syntax_txt->blockSignals(false); + syntax_conf_sel->blockSignals(false); + } +} diff --git a/apps/pgmodeler-se/src/schemaeditorform.h b/apps/pgmodeler-se/src/schemaeditorform.h new file mode 100644 index 0000000000..eb117ce321 --- /dev/null +++ b/apps/pgmodeler-se/src/schemaeditorform.h @@ -0,0 +1,79 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup pgmodeler-se +\class SchemaEditorForm +\brief Implements the pgModeler's schema files editor and syntax checker. +*/ + +#ifndef SCHEMA_EDITOR_FORM_H +#define SCHEMA_EDITOR_FORM_H + +#include +#include +#include "ui_schemaeditorform.h" +#include "widgets/numberedtexteditor.h" +#include "utils/syntaxhighlighter.h" +#include "widgets/fileselectorwidget.h" + +class SchemaEditorForm: public QWidget, public Ui::SchemaEditorForm { + private: + Q_OBJECT + + static const QString UntitledFile; + + NumberedTextEditor *syntax_txt, *dtd_txt; + + SyntaxHighlighter *syntax_hl, *dtd_hl; + + FileSelectorWidget *syntax_conf_sel; + + QActionGroup *stx_action_grp; + + QMenu syntax_cfg_menu; + + void showEvent(QShowEvent *) override; + + void closeEvent(QCloseEvent *event) override; + + bool eventFilter(QObject *object, QEvent *event) override; + + QStringList showFileDialog(bool save_mode); + + public: + explicit SchemaEditorForm(QWidget *parent = nullptr); + void loadFiles(const QStringList &filenames); + bool hasModifiedEditors(); + + private slots: + void loadSyntaxConfig(); + void applySyntaxConfig(bool from_temp_file = true); + void saveSyntaxConfig(); + void addEditorTab(const QString &filename = ""); + void closeEditorTab(int idx, bool confirm_close = true); + void loadFile(); + void saveFile(bool save_as = false); + void setTabModified(bool modified); + void indentAll(); + void saveAll(); + void closeAll(); + void loadSyntaxFromCurrentTab(); +}; + +#endif diff --git a/apps/pgmodeler-se/src/sourceeditorwidget.cpp b/apps/pgmodeler-se/src/sourceeditorwidget.cpp new file mode 100644 index 0000000000..25d222c173 --- /dev/null +++ b/apps/pgmodeler-se/src/sourceeditorwidget.cpp @@ -0,0 +1,339 @@ +#include "sourceeditorwidget.h" +#include "messagebox.h" +#include "guiutilsns.h" +#include "utilsns.h" + +QPalette SourceEditorWidget::def_editor_pal; + +attribs_map SourceEditorWidget::snippets = { + {"ifend", "%if {} %then\n\n%end\n"}, + {"ifelseend", "%if {} %then\n\n%else\n\n%end\n"}, + {"ifexpr", "%if ({}) %then\n\n%end\n"}, + {"ifexprelse", "%if ({}) %then\n\n%else\n\n%end\n"}, + {"setattrstr", "%set {} \"\"\n"}, + {"setattrtxt", "%set {} [ ]\n"}, + {"unsetattr", "%unset {}\n"}, + {"unsetattr", "%unset {}\n"}, +}; + +SourceEditorWidget::SourceEditorWidget(QWidget *parent) : QWidget(parent) +{ + setupUi(this); + + is_modified = false; + curr_sytax_cfg = GlobalAttributes::SchHighlightConf; + + editor_txt = GuiUtilsNs::createNumberedTextEditor(editor_parent); + def_editor_pal = editor_txt->palette(); + + editor_hl = new SyntaxHighlighter(editor_txt); + find_wgt = new FindReplaceWidget(editor_txt, find_parent); + find_parent->setVisible(false); + + code_compl_wgt = new CodeCompletionWidget(editor_txt); + code_compl_wgt->configureCompletion(nullptr, editor_hl); + + source_file_sel = new FileSelectorWidget(source_file_parent); + source_file_sel->setReadOnly(true); + source_file_parent->setVisible(false); + + QVBoxLayout *vbox = new QVBoxLayout(source_file_parent); + vbox->setContentsMargins(0, 0, 0, 0); + vbox->addWidget(source_file_sel); + + for(auto &itr : snippets) + code_compl_wgt->insertCustomItem(itr.first, itr.second, QPixmap(GuiUtilsNs::getIconPath("codesnippet"))); + + vbox = new QVBoxLayout(find_parent); + vbox->setContentsMargins(0, 0, 0, GuiUtilsNs::LtMargin); + vbox->addWidget(find_wgt); + + indent_tb->setMenu(&indent_opts_menu); + act_break_inline_ifs = indent_opts_menu.addAction(tr("Break inline ifs")); + act_break_inline_ifs->setCheckable(true); + act_break_inline_ifs->setChecked(false); + + connect(code_compl_wgt, &CodeCompletionWidget::s_wordSelected, this, &SourceEditorWidget::handleSelectedSnippet); + connect(find_wgt, &FindReplaceWidget::s_hideRequested, find_tb, &QToolButton::toggle); + connect(validate_tb, &QToolButton::clicked, this, &SourceEditorWidget::validateSyntax); + connect(indent_tb, &QToolButton::clicked, this, &SourceEditorWidget::applyIndentation); + connect(editor_txt, &NumberedTextEditor::modificationChanged, this, &SourceEditorWidget::restoreEditorPalette); + connect(editor_txt, &NumberedTextEditor::undoAvailable, this, &SourceEditorWidget::setModified); + connect(editor_txt, &NumberedTextEditor::cursorPositionChanged, this, &SourceEditorWidget::restoreEditorPalette); + connect(find_tb, &QToolButton::toggled, find_parent, &QWidget::setVisible); +} + +void SourceEditorWidget::saveFile(const QString &filename) +{ + UtilsNs::saveFile(filename, editor_txt->toPlainText().toUtf8()); + + validate_tb->setEnabled(filename.endsWith(GlobalAttributes::SchemaExt)); + indent_tb->setEnabled(filename.endsWith(GlobalAttributes::SchemaExt)); + this->filename = filename; + source_file_sel->setSelectedFile(filename); + source_file_parent->setVisible(true); +} + +void SourceEditorWidget::loadSyntaxConfig(const QString &filename) +{ + try + { + editor_hl->loadConfiguration(filename); + editor_hl->rehighlight(); + curr_sytax_cfg = QFileInfo(filename).baseName(); + } + catch(Exception &e) + { + throw Exception(e.getErrorMessage(), e.getErrorCode(), __PRETTY_FUNCTION__, __FILE__, __LINE__, &e); + } +} + +void SourceEditorWidget::handleSelectedSnippet(const QString &snippet) +{ + QTextCursor tc = editor_txt->textCursor(); + tc.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + tc.removeSelectedText(); + tc.insertText(snippets[snippet]); +} + +QString SourceEditorWidget::getCurrentSyntaxConfig() +{ + return curr_sytax_cfg; +} + +void SourceEditorWidget::loadFile(const QString &filename) +{ + if(filename.isEmpty()) + return; + + bool enable = filename.endsWith(GlobalAttributes::SchemaExt); + + editor_txt->setPlainText(UtilsNs::loadFile(filename)); + validate_tb->setEnabled(enable); + indent_tb->setEnabled(enable); + code_compl_wgt->setEnabled(enable); + this->filename = filename; + source_file_sel->setSelectedFile(filename); + source_file_parent->setVisible(true); + + QString ext = "." + QFileInfo(filename).suffix(); + + if(ext == GlobalAttributes::DbModelExt || + ext == ".xml" || + ext == GlobalAttributes::ConfigurationExt || + ext == GlobalAttributes::ObjMetadataExt) + curr_sytax_cfg = GlobalAttributes::XMLHighlightConf; + else if(ext == ".sql") + curr_sytax_cfg = GlobalAttributes::SQLHighlightConf; + else + curr_sytax_cfg = GlobalAttributes::SchHighlightConf; +} + +void SourceEditorWidget::validateSyntax() +{ + SchemaParser schparser; + Messagebox msgbox; + + try + { + editor_txt->setPalette(def_editor_pal); + schparser.ignoreEmptyAttributes(true); + schparser.ignoreUnkownAttributes(true); + schparser.loadBuffer(editor_txt->toPlainText()); + schparser.getSourceCode({}); + + msgbox.show(tr("No lexical or sytactical errors found."), Messagebox::InfoIcon); + } + catch(Exception &e) + { + // When founding an error we try to highlight the exact portion of the document where to problem is + QTextCursor cursor(editor_txt->document()->findBlockByLineNumber(schparser.getCurrentLine() - 1)); + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, schparser.getCurrentColumn()); + + editor_txt->blockSignals(true); + editor_txt->setTextCursor(cursor); + editor_txt->blockSignals(false); + + // Changing the text selection color so the user can see where the problem is + QPalette pal = editor_txt->palette(); + pal.setColor(QPalette::Highlight, QColor("#f00000")); + pal.setColor(QPalette::HighlightedText, QColor("#ffffff")); + editor_txt->setPalette(pal); + + msgbox.show(e); + } +} + +void SourceEditorWidget::restoreEditorPalette() +{ + editor_txt->setPalette(def_editor_pal); +} + +void SourceEditorWidget::applyIndentation() +{ + QStringList buffer = editor_txt->toPlainText().split(QChar::LineFeed); + int if_level = 0, comment_pos = -1, line_count = buffer.size(); + bool found_cond = false, found_if = false, inline_ifend = false; + QString cond_pattern = QString("^(( )|(\\t))*(%1)"), line, + tk_if = SchemaParser::CharStartConditional + SchemaParser::TokenIf, + tk_then = SchemaParser::CharStartConditional + SchemaParser::TokenThen, + tk_else = SchemaParser::CharStartConditional + SchemaParser::TokenElse, + tk_end = SchemaParser::CharStartConditional + SchemaParser::TokenEnd; + QRegularExpression inline_if_regexp(QString("(%1)(.)+(%2)").arg(tk_if).arg(tk_end)); + + for(int ln_idx = 0; ln_idx < line_count; ln_idx++) + { + line = buffer[ln_idx]; + comment_pos = line.indexOf(SchemaParser::CharComment); + inline_ifend = line.contains(inline_if_regexp); + + if(line.contains(QRegularExpression(cond_pattern.arg(tk_if))) && !inline_ifend) + { + if_level++; + found_if = found_cond = true; + } + else if(line.contains(QRegularExpression(cond_pattern.arg(tk_else))) || + line.contains(QRegularExpression(cond_pattern.arg(tk_end)))) + found_cond = true; + + // If the current line is an inline if: %if ... %then ... %end, we break it + if(act_break_inline_ifs->isChecked() && inline_ifend) + { + line.replace(tk_if, QChar::LineFeed + tk_if); + line.replace(tk_then, tk_then + QChar::LineFeed); + line.replace(tk_else, QChar::LineFeed + tk_else + QChar::LineFeed); + line.replace(tk_end, QChar::LineFeed + tk_end + QChar::LineFeed ); + + /* If the line was broke ( presence of \n) we split the resulting string + * and insert the new lines in the buffer and restart the indentation process */ + if(line.contains(QChar::LineFeed)) + { + QStringList buf_aux = line.split(QChar::LineFeed, Qt::SkipEmptyParts); + buffer.removeAt(ln_idx); + + for(auto itr = buf_aux.rbegin(); itr != buf_aux.rend(); itr++) + buffer.insert(ln_idx, *itr); + + ln_idx = 0; + found_cond = found_if = false; + if_level = 0; + line_count = buffer.size(); + continue; + } + } + + line = line.simplified(); + + if(!line.isEmpty()) + { + line = line.rightJustified(line.size() + if_level + (found_cond ? -1 : 0), QChar::Tabulation); + + if(!inline_ifend) + if_level -= line.mid(0, comment_pos).count(QString("%1%2").arg(SchemaParser::CharStartConditional).arg(SchemaParser::TokenEnd)); + } + + buffer[ln_idx] = line; + found_cond = found_if = false; + } + + QRegularExpression cond_tk_regexp(QString("^(( )|(\\t))*(%1)[a-z]+").arg(SchemaParser::CharStartConditional)); + QString prev_line, next_line, next_next_line, + tk_set = SchemaParser::CharStartConditional + SchemaParser::TokenSet, + tk_unset = SchemaParser::CharStartConditional + SchemaParser::TokenUnset; + + for(int ln_idx = 0; ln_idx < buffer.count() - 1; ln_idx++) + { + line = buffer[ln_idx].mid(0, buffer[ln_idx].indexOf(SchemaParser::CharComment)); + + // Ignoring the line if it contains a inline if + if(line.contains(inline_if_regexp)) + continue; + + // Capturing the previous, next lines without comment portion + prev_line = ln_idx > 0 ? buffer[ln_idx - 1].mid(0, buffer[ln_idx - 1].indexOf(SchemaParser::CharComment)) : ""; + next_line = ln_idx < buffer.count() - 1 ? buffer[ln_idx + 1].mid(0, buffer[ln_idx + 1].indexOf(SchemaParser::CharComment)) : ""; + next_next_line = ln_idx < buffer.count() - 2 ? buffer[ln_idx + 2].mid(0, buffer[ln_idx + 2].indexOf(SchemaParser::CharComment)) : ""; + + /* Removing the empty line in the following cases: + * 1) Between a two %end tokens + * 2) Between an %end and %else + * 3) Between an two %if tokens + * 4) Between an %else and %if | %set | %unset */ + if(next_line.isEmpty() && !next_next_line.isEmpty() && + ((line.contains(QRegularExpression(cond_pattern.arg(tk_end))) && + (next_next_line.contains(QRegularExpression(cond_pattern.arg(tk_else))) || + next_next_line.contains(QRegularExpression(cond_pattern.arg(tk_end))))) || + + ((line.contains(QRegularExpression(cond_pattern.arg(tk_if))) || + line.contains(QRegularExpression(cond_pattern.arg(tk_else)))) && + (next_next_line.contains(QRegularExpression(cond_pattern.arg(tk_if))) || + next_next_line.contains(QRegularExpression(cond_pattern.arg(tk_set))) || + next_next_line.contains(QRegularExpression(cond_pattern.arg(tk_unset))))))) + { + buffer.removeAt(ln_idx + 1); + ln_idx--; + continue; + } + + // Separating an end token from any conditional token in the next line + if(line.contains(QRegularExpression(cond_pattern.arg(tk_end))) && + !next_line.isEmpty() && + !next_line.contains(cond_tk_regexp)) + buffer[ln_idx].append(QChar::LineFeed); + + // Separating an closed plain text from the next line + else if(line.endsWith(SchemaParser::CharEndPlainText) && + !next_line.isEmpty() && + !next_line.contains(cond_tk_regexp)) + buffer[ln_idx].append(QChar::LineFeed); + + // If the current line has an %if and the previous is not a conditional instruction % + else if(line.contains(QRegularExpression(cond_pattern.arg(tk_if))) && + !prev_line.isEmpty() && + !prev_line.contains(cond_tk_regexp)) + buffer[ln_idx].prepend(QChar::LineFeed); + + // Separating an if token from previous end, set and unset + else if(line.contains(QRegularExpression(cond_pattern.arg(tk_if))) && + (prev_line.contains(tk_end) || + prev_line.contains(tk_set) || + prev_line.contains(tk_unset))) + buffer[ln_idx].prepend(QChar::LineFeed); + } + + /* Replacing the current code with the formatted one in such a way to preserve + * the undo/redo stack. This is achieved by selecting the whole text document + * and inserting the new text using the cursor. Using QPlainTextEdit::setPlainText + * will clear the stack. */ + editor_txt->blockSignals(true); + QTextCursor cursor = editor_txt->textCursor(); + cursor.movePosition(QTextCursor::Start); + cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + cursor.insertText(buffer.join(QChar::LineFeed)); + cursor = editor_txt->textCursor(); + editor_txt->moveCursor(QTextCursor::Start); + editor_txt->blockSignals(false); + setModified(true); +} + +void SourceEditorWidget::setModified(bool value) +{ + is_modified = value; + emit s_editorModified(value); +} + +void SourceEditorWidget::setDefaultEditorPalette(const QPalette &pal) +{ + def_editor_pal = pal; +} + +QString SourceEditorWidget::getFilename() +{ + return filename; +} + +bool SourceEditorWidget::isModified() +{ + return is_modified; +} diff --git a/apps/pgmodeler-se/src/sourceeditorwidget.h b/apps/pgmodeler-se/src/sourceeditorwidget.h new file mode 100644 index 0000000000..8f5a2a3ec5 --- /dev/null +++ b/apps/pgmodeler-se/src/sourceeditorwidget.h @@ -0,0 +1,102 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup pgmodeler-sc +\class SourceEditorWidget +\brief Implements the basic source code editor with minimal code completion for schema files. +*/ + +#ifndef SOURCE_EDITOR_WIDGET_H +#define SOURCE_EDITOR_WIDGET_H + +#include +#include "ui_sourceeditorwidget.h" +#include "widgets/numberedtexteditor.h" +#include "utils/syntaxhighlighter.h" +#include "widgets/findreplacewidget.h" +#include "widgets/codecompletionwidget.h" +#include "widgets/fileselectorwidget.h" + +class SourceEditorWidget: public QWidget, public Ui::SourceEditorWidget { + private: + Q_OBJECT + + static attribs_map snippets; + + static QPalette def_editor_pal; + + CodeCompletionWidget *code_compl_wgt; + + FileSelectorWidget *source_file_sel; + + NumberedTextEditor *editor_txt; + + SyntaxHighlighter *editor_hl; + + FindReplaceWidget *find_wgt; + + QString filename, curr_sytax_cfg; + + QAction *act_break_inline_ifs; + + QMenu indent_opts_menu; + + bool is_modified; + + public: + explicit SourceEditorWidget(QWidget *parent = nullptr); + + /*! \brief Defines the default pallete for text editor. + * This is used to restore the colors of the editor after an error is raised + * during syntax validation and the text selection color is changed to point the + * error location */ + static void setDefaultEditorPalette(const QPalette &pal); + + //! \brief Returns the file being handled by the editor + QString getFilename(); + + //! \brief Returns the current modification status of the editor + bool isModified(); + + QString getCurrentSyntaxConfig(); + + private slots: + //! \brief Validates the syntax of the editor's content (only for schema micro-language code) + void validateSyntax(); + + //! \brief Restores the editor default colors after highlighting an syntax error in a portion of the text + void restoreEditorPalette(); + + //! \brief Applies a custom identation on the editor's content (only for schema micro-language code) + void applyIndentation(); + + //! \brief Insert the selected snippet into the editors (only for schema micro-language code) + void handleSelectedSnippet(const QString &snippet); + + public slots: + void setModified(bool value); + void loadFile(const QString &filename); + void saveFile(const QString &filename); + void loadSyntaxConfig(const QString &filename); + + signals: + void s_editorModified(bool value); +}; + +#endif diff --git a/apps/pgmodeler-se/ui/aboutsewidget.ui b/apps/pgmodeler-se/ui/aboutsewidget.ui new file mode 100644 index 0000000000..f6329627e6 --- /dev/null +++ b/apps/pgmodeler-se/ui/aboutsewidget.ui @@ -0,0 +1,436 @@ + + + AboutSEWidget + + + Qt::NonModal + + + + 0 + 0 + 816 + 704 + + + + + 0 + 0 + + + + + 650 + 500 + + + + + 16777215 + 16777215 + + + + About pgModeler Schema Editor + + + + :/images/images/schemafile.png:/images/images/schemafile.png + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 100 + 100 + + + + + 100 + 100 + + + + + + + + + + :/images/images/schemafile.png + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + true + + + + pgModeler Schema Editor + + + Qt::AlignCenter + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + true + true + + + + + + + 0.0.0 + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 129 + 0 + + + + + + + + + 0 + 129 + 0 + + + + + + + + + 128 + 128 + 128 + + + + + + + + + true + false + + + + (BUILD_NUM) + + + Qt::AlignCenter + + + -1 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + false + + + + QFrame::NoFrame + + + Create, edit and verify the syntax of files written in pgModeler's schema micro-language. You can also tweak the tool's syntax highlighting settings to be used by the main GUI application. + + + Qt::PlainText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 0 + + + Qt::TextSelectableByMouse + + + + + + + + 0 + 0 + + + + License + + + + 5 + + + 5 + + + 5 + + + 5 + + + + + QFrame::Sunken + + + QAbstractScrollArea::AdjustToContents + + + false + + + QTextEdit::WidgetWidth + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Noto Sans'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier'; font-size:11pt;">pgModeler - PostgreSQL Database Modeler<br />Copyright 2006-2021 - Raphael Araújo e Silva<br /><br />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 version 3.<br /><br />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.<br /><br />The complete text of GPLv3 is at LICENSE file on pgModeler's source code root directory. Also, you can get the complete GNU General Public License at &lt;</span><a href="http://www.gnu.org/licenses"><span style=" font-family:'Courier'; font-size:11pt; text-decoration: underline; color:#0000ff;">http://www.gnu.org/licenses</span></a><span style=" font-family:'Courier'; font-size:11pt;">&gt;</span></p></body></html> + + + false + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + 77 + 48 + + + + pgModeler is proudly a brazilian software! + + + + + + + + + :/images/images/brazil_flag.png + + + true + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Raphael Araújo e Silva &lt;<a href="mailto:raphael@pgmodeler.com.br"><span style=" text-decoration: underline; color:#0057ae;">raphael@pgmodeler.io</span></a>&gt;</p></body></html> + + + Qt::AutoText + + + 5 + + + true + + + + + + + + + + + + + + + + diff --git a/apps/pgmodeler-se/ui/schemaeditorform.ui b/apps/pgmodeler-se/ui/schemaeditorform.ui new file mode 100644 index 0000000000..13c05d6eaa --- /dev/null +++ b/apps/pgmodeler-se/ui/schemaeditorform.ui @@ -0,0 +1,989 @@ + + + SchemaEditorForm + + + + 0 + 0 + 1792 + 1075 + + + + + 800 + 600 + + + + pgModeler Schema Editor + + + + :/images/images/schemafile.png:/images/images/schemafile.png + + + + 0 + + + 0 + + + 5 + + + 5 + + + 5 + + + + + Qt::Horizontal + + + 5 + + + true + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 5 + + + + + + 16777215 + 16777215 + + + + QTabWidget::North + + + true + + + + + + + + false + + + + 0 + + + 5 + + + 0 + + + 0 + + + 5 + + + + + + 0 + 0 + + + + Syntax file: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + false + + + Save && apply + + + + :/icons/icons/save.png:/icons/icons/save.png + + + + 25 + 25 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 25 + 25 + + + + + 25 + 25 + + + + + + + Qt::AutoText + + + :/icons/icons/alert.png + + + true + + + + + + + false + + + Apply only + + + + :/icons/icons/confirm.png:/icons/icons/confirm.png + + + + 25 + 25 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + false + + + Reload + + + + :/icons/icons/refresh.png:/icons/icons/refresh.png + + + + 25 + 25 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + 0 + 0 + + + + + false + false + false + true + + + + The syntax settings below have changed. Click <strong>Save & apply</strong> to persit the modifications to config file and apply them; <strong>Apply only</strong> to use the modified settings on-the-fly on the current editor without save the changes to the configuration file; or <strong>Reload</strong> to load the file again from the last time that it was saved. <strong>NOTE:</strong> switching to another editor tab will cause all modifications below to be lost. + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + 0 + + + + <p>Instead of loading the configuration file at user's local storage, loads the template one inside the pgModeler's installation folder.</p> + + + Use template configuration file + + + + + + + 0 + + + + XML + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + DTD + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + QFrame::Plain + + + Qt::Horizontal + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + Save changes to another file + + + Save as + + + + :/icons/icons/saveas.png:/icons/icons/saveas.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Exit + + + + :/icons/icons/exit.png:/icons/icons/exit.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Open a new editor + + + New + + + + :/icons/icons/new.png:/icons/icons/new.png + + + + 32 + 32 + + + + Ctrl+N + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + Save changes + + + Save + + + + :/icons/icons/save.png:/icons/icons/save.png + + + + 32 + 32 + + + + Ctrl+S + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Load files + + + Load + + + + :/icons/icons/open.png:/icons/icons/open.png + + + + 32 + 32 + + + + Ctrl+L + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + About + + + + :/icons/icons/help.png:/icons/icons/help.png + + + + 32 + 32 + + + + F1 + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + Choose the syntax highlighting mode + + + Syntax + + + + :/icons/icons/xmlcode.png:/icons/icons/xmlcode.png + + + + 32 + 32 + + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextUnderIcon + + + true + + + Qt::NoArrow + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + Apply identation to all open editors + + + Indent all + + + + :/icons/icons/indent.png:/icons/icons/indent.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + Save all + + + + :/icons/icons/saveall.png:/icons/icons/saveall.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + Close all + + + + :/icons/icons/close.png:/icons/icons/close.png + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + + + + + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 169 + 35 + + + + + 169 + 35 + + + + + + + + + + Qt::PlainText + + + :/images/images/pgmodeler_name.png + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + new_tb + load_tb + save_tb + save_as_tb + save_all_tb + close_all_tb + syntax_tb + indent_all_tb + about_tb + exit_tb + editors_tbw + tabWidget + use_tmpl_file_chk + save_conf_tb + apply_conf_tb + reload_conf_tb + + + + + + + diff --git a/apps/pgmodeler-se/ui/sourceeditorwidget.ui b/apps/pgmodeler-se/ui/sourceeditorwidget.ui new file mode 100644 index 0000000000..b52c26e116 --- /dev/null +++ b/apps/pgmodeler-se/ui/sourceeditorwidget.ui @@ -0,0 +1,242 @@ + + + SourceEditorWidget + + + + 0 + 0 + 1212 + 736 + + + + Form + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + + + + 5 + + + 5 + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Validate the syntax of the schema file + + + Validate + + + + :/icons/icons/validatesch.png:/icons/icons/validatesch.png + + + + 28 + 28 + + + + F5 + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon + + + false + + + Qt::NoArrow + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Apply custom indentation to the code + + + Indent + + + + :/icons/icons/indent.png:/icons/icons/indent.png + + + + 28 + 28 + + + + Ctrl+I + + + QToolButton::MenuButtonPopup + + + Qt::ToolButtonTextBesideIcon + + + false + + + Qt::NoArrow + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + Find + + + + :/icons/icons/findtext.png:/icons/icons/findtext.png + + + + 28 + 28 + + + + Ctrl+F + + + true + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon + + + false + + + Qt::NoArrow + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + diff --git a/apps/pgmodeler/pgmodeler.pro b/apps/pgmodeler/pgmodeler.pro new file mode 100644 index 0000000000..1108381c84 --- /dev/null +++ b/apps/pgmodeler/pgmodeler.pro @@ -0,0 +1,30 @@ +include(../apps.pri) + +TEMPLATE = app +TARGET = pgmodeler + +unix:LIBS += $$QMAKE_LIBS_EXECINFO +windows:RC_FILE=res/windows_ico.qrc +windows:RCC_DIR=src/ +windows: DESTDIR = $$PWD + +HEADERS += src/pgmodelerapp.h + +SOURCES += src/main.cpp \ + src/pgmodelerapp.cpp + +# Deployment settings +target.path = $$BINDIR +INSTALLS = target + +macx { + macdeps.files = $$PWD/res/Resources $$PWD/res/Info.plist $$PWD/res/PkgInfo + macdeps.path = $$PREFIX + + macscript.files = $$PWD/res/startapp + macscript.path = $$BINDIR + + INSTALLS += macdeps macscript +} + + diff --git a/main/res/Info.plist b/apps/pgmodeler/res/Info.plist similarity index 94% rename from main/res/Info.plist rename to apps/pgmodeler/res/Info.plist index 330902878e..238fe3d271 100644 --- a/main/res/Info.plist +++ b/apps/pgmodeler/res/Info.plist @@ -25,7 +25,7 @@ CFBundleDisplayName pgModeler CFBundleIdentifier - br.com.pgmodeler.pgModeler + io.pgmodeler.pgModeler CFBundleInfoDictionaryVersion 1.0 CFBundlePackageType @@ -33,7 +33,7 @@ CFBundleSignature ???? CFBundleVersion - 0.8.0 + 0.9.4 CSResourcesFileMapped NSPrincipalClass diff --git a/main/res/PkgInfo b/apps/pgmodeler/res/PkgInfo similarity index 100% rename from main/res/PkgInfo rename to apps/pgmodeler/res/PkgInfo diff --git a/main/res/Resources/empty.lproj b/apps/pgmodeler/res/Resources/empty.lproj similarity index 100% rename from main/res/Resources/empty.lproj rename to apps/pgmodeler/res/Resources/empty.lproj diff --git a/apps/pgmodeler/res/Resources/pgmodeler.icns b/apps/pgmodeler/res/Resources/pgmodeler.icns new file mode 100644 index 0000000000..6d62e86368 Binary files /dev/null and b/apps/pgmodeler/res/Resources/pgmodeler.icns differ diff --git a/apps/pgmodeler/res/Resources/pgmodeler_dbm.icns b/apps/pgmodeler/res/Resources/pgmodeler_dbm.icns new file mode 100644 index 0000000000..fad7dcc34f Binary files /dev/null and b/apps/pgmodeler/res/Resources/pgmodeler_dbm.icns differ diff --git a/apps/pgmodeler/res/windows_ico.ico b/apps/pgmodeler/res/windows_ico.ico new file mode 100644 index 0000000000..a3f57aafb0 Binary files /dev/null and b/apps/pgmodeler/res/windows_ico.ico differ diff --git a/main/res/windows_ico.qrc b/apps/pgmodeler/res/windows_ico.qrc similarity index 100% rename from main/res/windows_ico.qrc rename to apps/pgmodeler/res/windows_ico.qrc diff --git a/apps/pgmodeler/res/windows_ico1.ico b/apps/pgmodeler/res/windows_ico1.ico new file mode 100644 index 0000000000..1beed722c4 Binary files /dev/null and b/apps/pgmodeler/res/windows_ico1.ico differ diff --git a/apps/pgmodeler/src/main.cpp b/apps/pgmodeler/src/main.cpp new file mode 100644 index 0000000000..d2e96f7d81 --- /dev/null +++ b/apps/pgmodeler/src/main.cpp @@ -0,0 +1,136 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +#include "pgmodelerapp.h" +#include "mainwindow.h" + +#ifndef Q_OS_WIN +#include "execinfo.h" +#endif + +void startCrashHandler(int signal) +{ + QFile output; + QString lin, cmd; + + /** At the moment the backtrace function does not exists on MingW (Windows) this way + the code that generates the stacktrace is available only on Linux/Unix systems */ +#ifndef Q_OS_WIN + void *stack[30]; + size_t stack_size; + char **symbols=nullptr; + stack_size = backtrace(stack, 30); + symbols = backtrace_symbols(stack, stack_size); +#endif + + cmd=QString("\"%1\"").arg(GlobalAttributes::getPgModelerCHandlerPath()) + " -style " + GlobalAttributes::DefaultQtStyle; + + //Creates the stacktrace file + output.setFileName(GlobalAttributes::getTemporaryFilePath(GlobalAttributes::StacktraceFile)); + output.open(QFile::WriteOnly); + + if(output.isOpen()) + { + lin=QString("** pgModeler crashed after receive signal: %1 **\n\nDate/Time: %2 \nVersion: %3 \nBuild: %4 \n") + .arg(signal) + .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) + .arg(GlobalAttributes::PgModelerVersion) + .arg(GlobalAttributes::PgModelerBuildNumber); + + lin+=QString("Compilation Qt version: %1\nRunning Qt version: %2\n\n") + .arg(QT_VERSION_STR) + .arg(qVersion()); + + output.write(lin.toStdString().c_str(), lin.size()); + +#ifndef Q_OS_WIN + for(size_t i=0; i < stack_size; i++) + { + lin=QString("[%1] ").arg(stack_size-1-i) + QString(symbols[i]) + "\n"; + output.write(lin.toStdString().c_str(), lin.size()); + } + free(symbols); +#else + lin = "** Stack trace unavailable on Windows system **"; + output.write(lin.toStdString().c_str(), lin.size()); +#endif + + output.close(); + } + + /* Changing the working dir to the main executable in order to call the crash handler + if the PGMODELER_CHANDLER_PATH isn't set */ + QDir dir; + dir.cd(QApplication::applicationDirPath()); + + exit(1 + system(cmd.toStdString().c_str())); +} + +int main(int argc, char **argv) +{ + try + { + //Install a signal handler to start crashhandler when SIGSEGV or SIGABRT is emitted + signal(SIGSEGV, startCrashHandler); + signal(SIGABRT, startCrashHandler); + + GlobalAttributes::setCustomUiScaleFactor(); + PgModelerApp app(argc,argv); + int res=0; + + //Loading the application splash screen + QSplashScreen splash; + QPixmap pix(":images/images/pgmodeler_splash.png"); + + if(qApp->primaryScreen()->devicePixelRatio() > 1) + pix.setDevicePixelRatio(qApp->primaryScreen()->devicePixelRatio()); + else + pix = pix.scaledToWidth(320, Qt::SmoothTransformation); + + splash.setPixmap(pix); + splash.show(); + app.processEvents(); + + //Creates the main form + MainWindow fmain; + + fmain.show(); + splash.finish(&fmain); + + //Loading models via command line on MacOSX are disabled until the file association work correclty on that system +#ifndef Q_OS_MAC + QStringList params=app.arguments(); + params.pop_front(); + + //If the user specifies a list of files to be loaded + if(!params.isEmpty()) + fmain.loadModels(params); +#endif + + res = app.exec(); + app.closeAllWindows(); + + return res; + } + catch(Exception &e) + { + QTextStream ts(stdout); + ts << e.getExceptionsText(); + return enum_t(e.getErrorCode()); + } +} diff --git a/apps/pgmodeler/src/pgmodelerapp.cpp b/apps/pgmodeler/src/pgmodelerapp.cpp new file mode 100644 index 0000000000..622274ee89 --- /dev/null +++ b/apps/pgmodeler/src/pgmodelerapp.cpp @@ -0,0 +1,120 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ +#include "pgmodelerapp.h" +#include "globalattributes.h" +#include "messagebox.h" +#include "attributes.h" +#include "customuistyle.h" +#include + +PgModelerApp::PgModelerApp(int &argc, char **argv) : Application(argc,argv) +{ + QString plugin_name, plug_lang_dir, plug_lang_file; + QStringList dir_list; + QDir dir; + + try + { + //Creating the initial user's configuration + createUserConfiguration(true); + } + catch(Exception &e) + { + Messagebox msgbox; + msgbox.show(e); + } + + //Checking if the user specified another widget style using the -style param + bool using_style=false; + + for(int i=0; i < argc && !using_style; i++) + using_style=QString(argv[i]).contains("-style"); + + //If no custom style is specified we force the usage of Fusion (the default for Qt and pgModeler) + if(!using_style) + setStyle(new CustomUiStyle(GlobalAttributes::DefaultQtStyle)); + + //Changing the current working dir to the executable's directory in + QDir::setCurrent(this->applicationDirPath()); + + //Adding paths which executable will find plugins and it's dependecies + this->addLibraryPath(this->applicationDirPath()); + + //If pgModeler bundles plugins, add the root plugins path to lib search paths + if(dir.exists(GlobalAttributes::getPluginsPath())) + this->addLibraryPath(GlobalAttributes::getPluginsPath()); + + //Check if the temporary dir exists, if not, creates it. + if(!dir.exists(GlobalAttributes::getTemporaryPath())) + { + if(!dir.mkdir(GlobalAttributes::getTemporaryPath())) + { + Messagebox msg; + msg.show(Exception(Exception::getErrorMessage(ErrorCode::FileDirectoryNotWritten).arg(GlobalAttributes::getTemporaryPath()), + ErrorCode::FileDirectoryNotWritten, __PRETTY_FUNCTION__,__FILE__,__LINE__)); + } + } + + //Trying to identify if the user defined a custom UI language in the pgmodeler.conf file + QString lang_id = GlobalAttributes::getConfigParamFromFile(Attributes::UiLanguage, GlobalAttributes::GeneralConf); + + if(lang_id.isEmpty()) + lang_id = QLocale::system().name(); + + loadTranslation(lang_id); + + //Trying to load plugins translations + dir_list=QDir(GlobalAttributes::getPluginsPath() + + GlobalAttributes::DirSeparator, + "*", QDir::Name, QDir::AllDirs | QDir::NoDotAndDotDot).entryList(); + + while(!dir_list.isEmpty()) + { + plugin_name=dir_list.front(); + dir_list.pop_front(); + + //Configure the path to "lang" subdir at current plugin directory + plug_lang_dir=GlobalAttributes::getPluginsPath() + + GlobalAttributes::DirSeparator + plugin_name + + GlobalAttributes::DirSeparator + "lang" + + GlobalAttributes::DirSeparator; + + plug_lang_file=plugin_name + "." + lang_id; + loadTranslation(plug_lang_file, plug_lang_dir); + } +} + +bool PgModelerApp::notify(QObject *receiver, QEvent *event) +{ + try + { + return QApplication::notify(receiver,event); + } + catch(Exception &e) + { + Messagebox msg_box; + msg_box.show(e); + return false; + } + catch(...) + { + Messagebox msg_box; + msg_box.show(tr("Unknown exception caught!"), Messagebox::ErrorIcon); + return false; + } +} diff --git a/apps/pgmodeler/src/pgmodelerapp.h b/apps/pgmodeler/src/pgmodelerapp.h new file mode 100644 index 0000000000..4b0eff5209 --- /dev/null +++ b/apps/pgmodeler/src/pgmodelerapp.h @@ -0,0 +1,40 @@ +/* +# PostgreSQL Database Modeler (pgModeler) +# +# Copyright 2006-2023 - Raphael Araújo e Silva +# +# 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 version 3. +# +# 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. +# +# The complete text of GPLv3 is at LICENSE file on source code root directory. +# Also, you can get the complete GNU General Public License at +*/ + +/** +\ingroup pgmodeler +\class PgModelerApp +\brief This class inherits from QApplication and has the notify() method modified + to treat the exceptions raised by pgModeler components. +*/ + +#ifndef PGMODELER_APP_H +#define PGMODELER_APP_H + +#include "application.h" +#include +#include +#include + +class PgModelerApp: public Application { + public: + PgModelerApp(int & argc, char ** argv); + bool notify(QObject * receiver, QEvent * event); +}; + +#endif diff --git a/assets/conf/appearance.conf b/assets/conf/appearance.conf new file mode 100644 index 0000000000..960e2a7bdd --- /dev/null +++ b/assets/conf/appearance.conf @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/connections.conf b/assets/conf/connections.conf similarity index 100% rename from conf/connections.conf rename to assets/conf/connections.conf diff --git a/assets/conf/defaults/appearance.conf b/assets/conf/defaults/appearance.conf new file mode 100644 index 0000000000..5e24b2a3eb --- /dev/null +++ b/assets/conf/defaults/appearance.conf @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/defaults/connections.conf b/assets/conf/defaults/connections.conf similarity index 100% rename from conf/defaults/connections.conf rename to assets/conf/defaults/connections.conf diff --git a/assets/conf/defaults/diff-presets.conf b/assets/conf/defaults/diff-presets.conf new file mode 100644 index 0000000000..47c1baa3c2 --- /dev/null +++ b/assets/conf/defaults/diff-presets.conf @@ -0,0 +1,23 @@ + + + + + diff --git a/assets/conf/defaults/example.dbm b/assets/conf/defaults/example.dbm new file mode 100644 index 0000000000..a19f1a289f --- /dev/null +++ b/assets/conf/defaults/example.dbm @@ -0,0 +1,238 @@ + + + + + + + + + + + + ] $br +%end + + $br + $br + +%if %not {split} %and {datadictidx} %then + {datadictidx} +%end + +{objects} + +[ ] + + $br + $br diff --git a/assets/schemas/datadict/datadictidx.sch b/assets/schemas/datadict/datadictidx.sch new file mode 100644 index 0000000000..95fa6462b2 --- /dev/null +++ b/assets/schemas/datadict/datadictidx.sch @@ -0,0 +1,58 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + +%if {split} %then + [ + + + Data dictionary generated by pgModeler + + + ] +%end + +$br [

Data dictionary index

] + +{spc}
    +{spc}
  • [Database: ] {name} + +%if {table} %then + {spc}

  • Tables + {spc}
      + {table} + {spc}
    + {spc}
  • +%end + +%if {foreigntable} %then + {spc}

  • [Foreign tables] + {spc}
      + {foreigntable} + {spc}
    + {spc}
  • +%end + +%if {view} %then + {spc}

  • Views + {spc}
      + {view} + {spc}
    + {spc}
  • +%end + +{spc}
+$br + +%if {split} %then + + [ ] + + $br + +%end diff --git a/assets/schemas/datadict/index.sch b/assets/schemas/datadict/index.sch new file mode 100644 index 0000000000..7e37383337 --- /dev/null +++ b/assets/schemas/datadict/index.sch @@ -0,0 +1,16 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + +{spc}
+{spc} +{spc} +{spc} +{spc} +{spc} +{spc} + + +{spc} diff --git a/assets/schemas/datadict/item.sch b/assets/schemas/datadict/item.sch new file mode 100644 index 0000000000..939097954b --- /dev/null +++ b/assets/schemas/datadict/item.sch @@ -0,0 +1,11 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {split} %then + %set {link} {item} [.html] +%else + %set {link} \# {item} +%end + +$br [ ]
  • {item}
  • diff --git a/assets/schemas/datadict/link.sch b/assets/schemas/datadict/link.sch new file mode 100644 index 0000000000..7351e3d2e7 --- /dev/null +++ b/assets/schemas/datadict/link.sch @@ -0,0 +1,11 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {split} %then + %set {link} {name} [.html] +%else + %set {link} \# {name} +%end + + {name} diff --git a/assets/schemas/datadict/objects.sch b/assets/schemas/datadict/objects.sch new file mode 100644 index 0000000000..eb67a51280 --- /dev/null +++ b/assets/schemas/datadict/objects.sch @@ -0,0 +1,110 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + +%if ({type-class} == "table") %then + %set {colspan} 8 +%else + %set {colspan} 5 +%end + +%if {columns} %then + {columns} +%end + +%if {constraints} %then + {spc} + {spc} + {spc} +%end + +%if {indexes} %then + {spc} + {spc} + {spc} +%end + +%if {triggers} %then + {spc} + {spc} + {spc} +%end + +%if {sequences} %then + {spc} + {spc} + {spc} +%end \ No newline at end of file diff --git a/assets/schemas/datadict/sequence.sch b/assets/schemas/datadict/sequence.sch new file mode 100644 index 0000000000..3c07c5d404 --- /dev/null +++ b/assets/schemas/datadict/sequence.sch @@ -0,0 +1,15 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + +{spc} +{spc} +{spc} +{spc} +{spc} +{spc} +{spc} + +{spc} diff --git a/assets/schemas/datadict/styles.sch b/assets/schemas/datadict/styles.sch new file mode 100644 index 0000000000..1dea69f3ef --- /dev/null +++ b/assets/schemas/datadict/styles.sch @@ -0,0 +1,224 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[body { +font-family: sans-serif; +color: \#333; +margin-left: 2em; +margin-top: 2em; +background-color: white; +} + +footer { +margin-top: 3em; +margin-bottom: .5em; +font-size: 90%; +} + +h3 { +margin-bottom: .5em; +} + +a { +color: \#4182c3; +text-decoration: none; +} + +a:hover { +color: \#080; +text-decoration: underline; +} + +\#index { +background-color: \#f8f9fa; +margin-block-end: 1.5em; +list-style: none; +display: inline-block; +padding: 1em; +border: 1px solid \#c0c0c0; +border-radius: 4px 4px 4px 4px; +} + +\#index li { +list-style: none; +margin: 0; +} + +\#index > li > ul { +padding-inline-start: 1em; +} + +.table, .foreigntable, .view { +font-size: 11pt; +border-collapse: collapse; +margin-top: 3em; +margin-bottom: 1em; +page-break-inside: avoid; +} + +.table caption { +background-color: \#d2f3ff; +} + +.foreigntable caption { +background-color: \#94f0b1; +} + +.view caption { +background-color: \#ffd8a1; +} + +.table, +.table caption, +.table th, +.table td { +border: 1px solid \#b4d0da; +} + +.foreigntable, +.foreigntable caption, +.foreigntable th, +.foreigntable td { +border: 1px solid \#6aad80; +} + +.view, +.view caption, +.view th, +.view td { +border: 1px solid \#ba7c00; +} + +.table caption, +.foreigntable caption, +.view caption { +border-bottom: 0; +} + +.table th, +.table .title, +.table .label{ +background-color: \#e9f8ff; +} + +.foreigntable th, +.foreigntable .title, +.foreigntable .label { +background-color: \#e2ffed; +} + +.view th, +.view .title, +.view .label { +background-color: \#ffebd2; +} + +.type-label { +float: right; +color: \#212529; +font-size: 70%; +font-weight: bold; +background-color: \#f8f9fa; +padding: 5px; +border-radius: 4px 4px 4px 4px; +} + +caption { +border-radius: 5px 5px 0 0; +} + +.nav-link { +font-size: 85%; +background-color: \#f2f2f3; +padding: 5px; +border-radius: 4px 4px 4px 4px; +color: \#212529; +font-weight: bold; +text-decoration: none; +margin-right: .5em; +} + +.nav-link:hover { +color: white; +background-color: \#007bff; +} + +td, th, caption, .title { +margin: 0; +padding: .3em; +} + +.title, th { +font-weight: bold; +text-align: center; +color: \#535c67; +} + +.data-type, .value, .constr-type { +font-family: monospace; +text-align: center; +} + +.constr-type { +color: \#24486c; +} + +.data-type { +color: \#b00; +} + +.bool-field { +text-align: center; +color: \#080; +} + +.label { +font-weight: bold; +color: \#444f53; +width: 1px; +white-space: nowrap; +} + +.tab-name { +font-size: 112%; +} + +.tab-description { +font-style: italic; +padding: .5em; +} + +.nested-tab-parent { +padding: 0; +} + +.nested-tab { +font-size: 11pt; +width: 100%; +border-collapse: collapse; +} + +.nested-tab > tbody > tr, +.nested-tab > tr{ +padding: 0; +} + +.nested-tab td { +border-bottom: 0; +border-left: 0; +} + +.nested-tab > tbody > tr:first-child td, +.nested-tab > tr:first-child td { +border-top: 0; +} + +.nested-tab td:last-child { +border-right: 0; +} + +.max-td-wth { +max-width: 500px; +} + +] diff --git a/assets/schemas/datadict/table.sch b/assets/schemas/datadict/table.sch new file mode 100644 index 0000000000..ca9c82ad3d --- /dev/null +++ b/assets/schemas/datadict/table.sch @@ -0,0 +1,117 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if ({type-class} == "table") %then + %set {colspan} 8 +%else + %set {colspan} 5 +%end + +%set {spc} $br [ ] + + +
    {name} {type} {columns}

    {expressions}

    {predicate}

    {comment}

    + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + + {constraints} + + {spc}
    Constraints
    Name Type Column(s) References Expression Description
    + {spc}
    + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + + {indexes} + + {spc}
    Indexes
    Name Type Column(s) Expression(s) Predicate Description
    + {spc}
    + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + + {triggers} + + {spc}
    Triggers
    Name Attributes Function [Firing mode] [On event(s)] [Per row] Condition References Description
    + {spc}
    + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + {spc} + + {sequences} + + {spc}
    Sequences
    Name Cyclic [Min. value] [Max. value] Column(s) Description
    + {spc}
    {name} {cycle} {min-value} {max-value} {columns}

    {comment}

    +{spc} +{spc} + +%if {comment} %then + {spc} + {spc} + {spc} +%end + +%if {columns} %then + {spc} + {spc} + {spc} + + %if ({type-class} == "table") %then + {spc} + {spc} + {spc} + %end + + {spc} + {spc} + {spc} + {spc} +%else + {spc} + {spc} + {spc} +%end + +{spc} +{spc} + +%if {objects} %then + {objects} +%end + +{spc} + +%if {inherit} %or {partitioned-table} %or {partition-tables} %then + {spc} + {spc} + {spc} + {spc} + {spc} $br +%end + +$br
    +{spc} {schema}.{name} +{spc} {type} +{spc}
    + {comment} + {spc}
    Name [Data type]PKFKUQ[Not null][Default value] Description
    + {spc} [No columns] + {spc}
    + {spc} + + %if {inherit} %then + {spc} + {spc} + {spc} + {spc} + %end + + %if {partitioned-table} %then + {spc} + {spc} + {spc} + {spc} + %end + + %if {partition-tables} %then + {spc} + {spc} + {spc} + {spc} + %end + + {spc}
    Inherits: {inherit}
    [Partition of:] {partitioned-table}
    [Partitions:] {partition-tables}
    + {spc}
    $br + + +%if {datadictidx} %then + $br
    + + %if {split} %and {previous} %then + {spc} [←] $sp {previous} + %end + + %if {split} %then + $br [ ] + %else + $br [ ] + %end + + [↑ Index] + + %if {split} %and {next} %then + {spc} {next} $sp [→] + %end + + $br
    $br +%end diff --git a/assets/schemas/datadict/trigger.sch b/assets/schemas/datadict/trigger.sch new file mode 100644 index 0000000000..f9cdb69dcf --- /dev/null +++ b/assets/schemas/datadict/trigger.sch @@ -0,0 +1,29 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + +{spc} +{spc} {name} +{spc} {attributes} +{spc} {function} +{spc} {firing-type} +{spc} {events} +{spc} {per-line} +{spc}

    {condition}

    + +{spc} + %if {ref-table} %then + %if {split} %then + {ref-table} + %else + {ref-table} + %end + %end +{spc} + +{spc}

    {comment}

    + + +{spc} diff --git a/assets/schemas/datadict/view.sch b/assets/schemas/datadict/view.sch new file mode 100644 index 0000000000..010f1adb60 --- /dev/null +++ b/assets/schemas/datadict/view.sch @@ -0,0 +1,82 @@ +# Template code for data dictionary generation +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {spc} $br [ ] + + +{spc} +{spc} + +%if {comment} %then + {spc} + {spc} + {spc} +%end + +%if {columns} %then + {spc} + {spc} + {spc} + {spc} +%else + {spc} + {spc} + {spc} +%end + +{spc} +{spc} + +%if {objects} %then + {objects} +%end + +{spc} + + +%if {references} %then + {spc} + {spc} + {spc} + {spc} + {spc} $br +%end + +$br
    +{spc} {schema}.{name} +{spc} {type} +{spc}
    + {comment} + {spc}
    Name[Data type]
    + {spc} [No columns] + {spc}
    + {spc} + {spc} + {spc} + {spc} + {spc} + {spc}
    References: {references}
    + {spc}
    $br + +%if {datadictidx} %then + $br
    + + %if {split} %and {previous} %then + {spc} [←] $sp {previous} + %end + + %if {split} %then + $br [ ] + %else + $br [ ] + %end + + [↑ Index] + + %if {split} %and {next} %then + {spc} {next} $sp [→] + %end + + $br
    $br +%end diff --git a/assets/schemas/sql/aggregate.sch b/assets/schemas/sql/aggregate.sch new file mode 100644 index 0000000000..953f0d71c2 --- /dev/null +++ b/assets/schemas/sql/aggregate.sch @@ -0,0 +1,35 @@ +# SQL definition for aggregate functions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE AGGREGATE ] {name} [ (]{types}[) (] $br +$tb [SFUNC = ] {transition}, $br +$tb [STYPE = ] {state-type} $br +%if {final} %then $tb [,FINALFUNC = ] {final} $br %end +%if {initial-cond} %then $tb [,INITCOND = ] {initial-cond} $br %end +%if {sort-op} %then $tb [,SORTOP = ] {sort-op} $br %end +); + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/cast.sch b/assets/schemas/sql/cast.sch new file mode 100644 index 0000000000..e2f868ba02 --- /dev/null +++ b/assets/schemas/sql/cast.sch @@ -0,0 +1,44 @@ +# SQL definition for type casts +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: cast] ( {source-type} [,] {destiny-type} ) [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE CAST (] {source-type} [ AS ] {destiny-type} ) $br + +%if {io-cast} %then + $tb [WITH INOUT ] +%else + %if {function} %then + $tb [WITH FUNCTION ] {function} + %else + $tb [WITHOUT FUNCTION] + %end +%end + +%if {cast-type} %then + $br $tb [AS ] {cast-type} +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/collation.sch b/assets/schemas/sql/collation.sch new file mode 100644 index 0000000000..43fda784a8 --- /dev/null +++ b/assets/schemas/sql/collation.sch @@ -0,0 +1,89 @@ +# SQL definition for collations +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br +%set {attr-sep} [,] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE COLLATION ] {name} + +%if {collation} %then + [ FROM ] {collation} +%else + [ (] $br + + %if {locale} %then + [ LOCALE = '] + + {locale} + + %if {locale-mod} %then + @ {locale-mod} + %end + + ['] + %else + %if {lc-ctype} %then + [ LC_CTYPE = '] + + {lc-ctype} + + %if {lc-ctype-mod} %then + @ {lc-ctype-mod} + %end + + ['] + %end + + %if {lc-collate} %then + %if {lc-ctype} %then {attr-sep} %end + [ LC_COLLATE = '] + + {lc-collate} + + %if {lc-collate-mod} %then + @ {lc-collate-mod} + %end + + ['] + %end + %end + + %if ({pgsql-ver} >=f "10.0") %then + %if {provider} %then + %if {locale} %or {lc-collate} %or {lc-ctype} %then {attr-sep} %end + [ PROVIDER =] '{provider}' + %end + %end + + %if ({pgsql-ver} >=f "12.0") %then + %if {locale} %or {lc-collate} %or {lc-ctype} %or {provider} %then {attr-sep} %end + [ DETERMINISTIC = ] {deterministic} + %end + + $br [)] +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/column.sch b/assets/schemas/sql/column.sch new file mode 100644 index 0000000000..3757ff1b5b --- /dev/null +++ b/assets/schemas/sql/column.sch @@ -0,0 +1,81 @@ +# SQL definition for columns +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {decl-in-table} %then + $tb +%else + [-- object: ] {name} [ | type: ] {sql-object} [ --] $br + [-- ] {drop} + + %if {table} %then + [ALTER TABLE ] {table} [ ADD COLUMN ] + %end +%end + +{name} $sp {type} + +%if {not-null} %then + [ NOT NULL] +%end + +%if {identity-type} %then + [ GENERATED ] {identity-type} [ AS IDENTITY ] + + %if {increment} %or {min-value} %or {max-value} %or {start} %or {cache} %or {cycle} %then + [(] + %end + + %if {increment} %then + [ INCREMENT BY ] {increment} + %end + + %if {min-value} %then + [ MINVALUE ] {min-value} + %end + + %if {max-value} %then + [ MAXVALUE ] {max-value} + %end + + %if {start} %then + [ START WITH ] {start} + %end + + %if {cache} %then + [ CACHE ] {cache} + %end + + %if {cycle} %then + [ CYCLE] + %end + + %if {increment} %or {min-value} %or {max-value} %or {start} %or {cache} %or {cycle} %then + [ )] + %end +%else + %if ({pgsql-ver} >=f "12.0") %and {generated} %then + [ GENERATED ALWAYS AS (] {default-value} [) STORED] + %else + %if {default-value} %then + [ DEFAULT ] {default-value} + %end + %end +%end + +%if {decl-in-table} %then + [,] +%else + [;] + + # This is a special token that pgModeler recognizes as end of DDL command + # when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! + $br [-- ddl-end --] $br + $br +%end + +%if %not {decl-in-table} %and {comment} %then + {comment} $br +%end + +$br diff --git a/assets/schemas/sql/comment.sch b/assets/schemas/sql/comment.sch new file mode 100644 index 0000000000..79c13f19b6 --- /dev/null +++ b/assets/schemas/sql/comment.sch @@ -0,0 +1,29 @@ +# SQL definition for comments +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {comment} %or ({comment}=="unset") %then + [COMMENT ON ] {sql-object} $sp + + %if ({sql-object}=="CONSTRAINT") %or ({sql-object}=="TRIGGER") %or + ({sql-object}=="RULE") %or ({sql-object}=="POLICY") %then + {name} [ ON ] {table} + %else + {signature} + %end + + [ IS ] + + %if ({comment}=="unset") %then + '' + %else + %if {escape-comment} %then E %end + '{comment}' + %end + + ; $br + + # This is a special token that pgModeler recognizes as end of DDL command + # when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! + [-- ddl-end --] $br +%end diff --git a/assets/schemas/sql/confparam.sch b/assets/schemas/sql/confparam.sch new file mode 100644 index 0000000000..47ef58b327 --- /dev/null +++ b/assets/schemas/sql/confparam.sch @@ -0,0 +1,5 @@ +# SQL definition for functions/procedures configuration parameters definition +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb [SET ] {name} [ = ] {value} $br diff --git a/assets/schemas/sql/constraint.sch b/assets/schemas/sql/constraint.sch new file mode 100644 index 0000000000..eed812ff6a --- /dev/null +++ b/assets/schemas/sql/constraint.sch @@ -0,0 +1,83 @@ +# SQL definition for constraints +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {decl-in-table} %then + $tb +%else + [-- object: ] {name} [ | type: ] {sql-object} [ --] $br + + %if {table} %then + [-- ] {drop} + [ALTER TABLE ] {table} [ ADD ] + %end +%end + +[CONSTRAINT ] {name} + +%if {ck-constr} %then + [ CHECK ] ({expression}) + + %if {no-inherit} %then [ NO INHERIT] %end + +%end + +%if {pk-constr} %then [ PRIMARY KEY ] ({src-columns}) %end +%if {uq-constr} %then [ UNIQUE ] ({src-columns}) %end + +%if {ex-constr} %then + [ EXCLUDE ] $br + $tb + + %if {index-type} %then + [USING ] {index-type} + %end + + ( {elements} $br $tb ) +%end + +%if {pk-constr} %or {uq-constr} %then + %if {factor} %then + %if {decl-in-table} %then $br $tb %end + [ WITH (FILLFACTOR = ] {factor} [)] + %end +%end + +%if {tablespace} %then + $br + %if {decl-in-table} %then $tb %end + %if {pk-constr} %or {uq-constr} %or {ex-constr} %then [USING INDEX TABLESPACE ] {tablespace} %end +%end + +%if {ex-constr} %and {expression} %then + $sp WHERE $sp ( {expression}) +%end + +%if {fk-constr} %then + [ FOREIGN KEY ] ({src-columns}) $br + + %if {decl-in-table} %then $tb %end + [REFERENCES ] {ref-table} $sp ({dst-columns}) + $sp {comparison-type} $br + + %if {decl-in-table} %then $tb %end + [ON DELETE ] {del-action} [ ON UPDATE ] {upd-action} +%end + +%if {deferrable} %then + [ DEFERRABLE ] {defer-type} +%end + +%if {decl-in-table} %then [,] +%else + [;] $br + + # This is a special token that pgModeler recognizes as end of DDL command + # when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! + [-- ddl-end --] $br +%end + +%if %not {decl-in-table} %and {comment} %then + {comment} $br +%end + +$br diff --git a/assets/schemas/sql/conversion.sch b/assets/schemas/sql/conversion.sch new file mode 100644 index 0000000000..4333199c9c --- /dev/null +++ b/assets/schemas/sql/conversion.sch @@ -0,0 +1,33 @@ +# SQL definition for encoding conversions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +CREATE %if {default} %then [ DEFAULT] %end + +[ CONVERSION ] {name} $br +$tb [FOR ] '{src-encoding}' [ TO ] '{dst-encoding}' $br +$tb [FROM ] {function}; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/database.sch b/assets/schemas/sql/database.sch new file mode 100644 index 0000000000..d47eb59118 --- /dev/null +++ b/assets/schemas/sql/database.sch @@ -0,0 +1,65 @@ +# SQL definition for databases +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE DATABASE ] {name} + +%if {template} %then + $br $tb [TEMPLATE = ] {template} +%end + +%if {encoding} %then + $br $tb [ENCODING = ] {encoding} +%end + +%if {lc-collate} %then + $br $tb [LC_COLLATE = ] {lc-collate} +%end + +%if {lc-ctype} %then + $br $tb [LC_CTYPE = ] {lc-ctype} +%end + +%if {tablespace} %then + $br $tb [TABLESPACE = ] {tablespace} +%end + +%if {owner} %then + $br $tb [OWNER = ] {owner} +%end + +%if {connlimit} %then + $br $tb [CONNECTION LIMIT = ] {connlimit} +%end + +%if ({is-template} == "true") %then + $br $tb [IS_TEMPLATE = ] {is-template} +%end + +%if ({allow-conns} == "false") %then + $br $tb [ALLOW_CONNECTIONS = ] {allow-conns} +%end +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/dbmodel.sch b/assets/schemas/sql/dbmodel.sch new file mode 100644 index 0000000000..0aff805c15 --- /dev/null +++ b/assets/schemas/sql/dbmodel.sch @@ -0,0 +1,57 @@ +# SQL definition for database model +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- Database generated with pgModeler (PostgreSQL Database Modeler).] $br +[-- pgModeler version: ] {pgmodeler-ver} $br +[-- PostgreSQL version: ] {pgsql-ver} $br +[-- Project Site: pgmodeler.io] $br +[-- Model Author: ] + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {author} %then + {author} +%else + --- +%end + +$br + +%if {export-to-file} %then + %if {role} %then {role} %end + + %if {tablespace} %then + [-- Tablespaces creation must be performed outside a multi lined SQL file. ] $br + [-- These commands were put in this file only as a convenience.] $br + [-- ] $br + {tablespace} $br + %end + + $br + + [-- Database creation must be performed outside a multi lined SQL file. ] $br + [-- These commands were put in this file only as a convenience.] $br + [-- ] $br + {database} $br +%end + +%if {function} %then + [SET check_function_bodies = false;] + + {ddl-end} $br +%end + +%if {schema} %then + {schema} + [SET search_path TO ] {search-path}; + {ddl-end} $br +%end + +%if {shell-types} %then {shell-types} %end +%if {objects} %then {objects} %end +%if {permission} %then {permission} %end + +$br diff --git a/assets/schemas/sql/domain.sch b/assets/schemas/sql/domain.sch new file mode 100644 index 0000000000..c04b5f5549 --- /dev/null +++ b/assets/schemas/sql/domain.sch @@ -0,0 +1,47 @@ +# SQL definition for domains +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE DOMAIN ] {name} [ AS ] {type} + +%if {collation} %then + $br $tb [COLLATE ] {collation} +%end + +%if {default-value} %then + $br $tb [DEFAULT ] {default-value} +%end + +%if {not-null} %then + $br $tb [NOT NULL] +%end + +%if {constraints} %then + {constraints} +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/domconstraint.sch b/assets/schemas/sql/domconstraint.sch new file mode 100644 index 0000000000..0e8c6beb2c --- /dev/null +++ b/assets/schemas/sql/domconstraint.sch @@ -0,0 +1,5 @@ +# SQL definition for domain's check constraint +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$br $tb CONSTRAINT $sp {name} $sp CHECK $sp ({expression}) diff --git a/assets/schemas/sql/drop.sch b/assets/schemas/sql/drop.sch new file mode 100644 index 0000000000..ca271a7481 --- /dev/null +++ b/assets/schemas/sql/drop.sch @@ -0,0 +1,29 @@ +# SQL command to drop an object +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if %not {domain} %and {constraint} %or {column} %then + %if %not {decl-in-table} %then + [ALTER TABLE ] {table} [ DROP ] {sql-object} [ IF EXISTS ] + %end +%else + [DROP ] {sql-object} [ IF EXISTS ] +%end + +%if {column} %or {constraint} %and %not {decl-in-table} %or {extension} %or {rule} %or {trigger} %or {policy} %then + {name} +%else + {signature} +%end + +%if {trigger} %or {rule} %or {policy} %then + [ ON ] {table} +%end + +%if {cascade} %and %not {database} %and %not {tablespace} %and %not {role} %and %not {usermapping} %then + [ CASCADE] +%end + +; + +$br [-- ddl-end --] $br diff --git a/assets/schemas/sql/element.sch b/assets/schemas/sql/element.sch new file mode 100644 index 0000000000..ae4c5b8077 --- /dev/null +++ b/assets/schemas/sql/element.sch @@ -0,0 +1,20 @@ +# SQL definition for operator class elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {function} %then + $tb FUNCTION $tb {stg-number} $tb {signature} +%end + +%if {operator} %then + $tb OPERATOR $tb {stg-number} $tb {signature} + + %if {opfamily} %then + [ FOR ORDER BY ] {opfamily} + %else + [ FOR SEARCH ] + %end +%end + +%if {storage} %then + $tb STORAGE $tb {type} +%end diff --git a/assets/schemas/sql/eventtrigger.sch b/assets/schemas/sql/eventtrigger.sch new file mode 100644 index 0000000000..73fdc10110 --- /dev/null +++ b/assets/schemas/sql/eventtrigger.sch @@ -0,0 +1,36 @@ +# SQL definition for event triggers +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE EVENT TRIGGER ] {name} +$br $tb [ON ] {event} + +%if {filter} %then + $br $tb [WHEN ] {filter} +%end + +$br $tb [EXECUTE PROCEDURE ] {function}; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/excelement.sch b/assets/schemas/sql/excelement.sch new file mode 100644 index 0000000000..9163aa22a4 --- /dev/null +++ b/assets/schemas/sql/excelement.sch @@ -0,0 +1,32 @@ +# SQL definition for exclude constraints elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$br $tb $sp $sp + +%if {column} %then + {column} +%else + %if {expression} %then + {expression} + %end +%end + +%if {opclass} %then + $sp {opclass} +%end + +%if {use-sorting} %then + %if {asc-order} %then + [ ASC ] + %else + [ DESC ] + %end + + %if {nulls-first} %then + [NULLS FIRST] + %else + [NULLS LAST] + %end +%end + +[ WITH ] {operator} diff --git a/assets/schemas/sql/extension.sch b/assets/schemas/sql/extension.sch new file mode 100644 index 0000000000..f98615ae3d --- /dev/null +++ b/assets/schemas/sql/extension.sch @@ -0,0 +1,42 @@ +# SQL definition for extensions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE EXTENSION ] {name} $br + +%if {schema} %then + [WITH SCHEMA ] {schema} +%end + +%if {cur-version} %then + $br [VERSION ] '{cur-version}' +%end + +%if {old-version} %then + $br [FROM ] '{old-version}' +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/foreigndatawrapper.sch b/assets/schemas/sql/foreigndatawrapper.sch new file mode 100644 index 0000000000..4a0a497610 --- /dev/null +++ b/assets/schemas/sql/foreigndatawrapper.sch @@ -0,0 +1,49 @@ +# SQL definition for foreign data wrappers +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ] {sql-object} $sp {name} $br + +%if %not {handler} %then + [NO HANDLER] +%else + [HANDLER ] {handler} +%end + +$br + +%if %not {validator} %then + [NO VALIDATOR] +%else + [VALIDATOR ] {validator} +%end + +%if {options} %then + $br [OPTIONS (] {options} ) +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/foreignserver.sch b/assets/schemas/sql/foreignserver.sch new file mode 100644 index 0000000000..da01329494 --- /dev/null +++ b/assets/schemas/sql/foreignserver.sch @@ -0,0 +1,45 @@ +# SQL definition for foreign server +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE SERVER ] {name} + +%if {type} %then + [ TYPE ] '{type}' +%end + +%if {version} %then + [ VERSION ] '{version}' +%end + +$br [FOREIGN DATA WRAPPER ] {fdw} + +%if {options} %then + $br [OPTIONS (] {options} ) +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/foreigntable.sch b/assets/schemas/sql/foreigntable.sch new file mode 100644 index 0000000000..302acf0460 --- /dev/null +++ b/assets/schemas/sql/foreigntable.sch @@ -0,0 +1,80 @@ +# SQL definition for foreign tables +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE FOREIGN TABLE ] {name} + +%if {partitioned-table} %then + $br [PARTITION OF ] {partitioned-table} $sp +%end + +%if %not {partitioned-table} %then + + [ (] $br + + %if %not {gen-alter-cmds} %then + %if {columns} %then + {columns} + %end + + %if {inh-columns} %then + {inh-columns} + %end + + %if {constraints} %then + {constraints} + %end + %end + + %if %not {constraints} %then $br %end + ) + +%else + %if %not {gen-alter-cmds} %and {partitioned-table} %and {constraints} %then + [ (] $br {constraints} $br [)] + %end +%end + +%if {partitioned-table} %then + $br [FOR VALUES ] {partition-bound-expr} +%end + +%if {ancestor-table} %then $br [ INHERITS(] {ancestor-table} [)] %end +$br [SERVER ] {server} +%if {options} %then $br [OPTIONS (] {options} [)] %end + +; + +{ddl-end} + +%if {gen-alter-cmds} %then + %if {columns} %then $br {columns} %end + %if {constraints} %then $br {constraints} %end +%end + +%if {comment} %then {comment} %end +%if {cols-comment} %then {cols-comment} %end +%if {owner} %then {owner} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +%if {initial-data} %then + $br {initial-data} $br +%end + +$br diff --git a/assets/schemas/sql/function.sch b/assets/schemas/sql/function.sch new file mode 100644 index 0000000000..bf9f83b9c2 --- /dev/null +++ b/assets/schemas/sql/function.sch @@ -0,0 +1,87 @@ +# SQL definition for functions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE FUNCTION ] {name} $sp ( %if {parameters} %then {parameters} %end ) $br +$tb [RETURNS ] + +%if {return-table} %then + [TABLE ] ( {return-table} ) +%else + %if {returns-setof} %then [SETOF ] %end + {return-type} +%end + +$br + + +$tb [LANGUAGE ] {language} $br + +%if {transform-types} %then + $tb TRANSFORM {transform-types} $br +%end + +%if {window-func} %then + $tb WINDOW $br +%end + +$tb {function-type} $sp %if {leakproof} %then LEAKPROOF %end $br + +$tb {behavior-type} $br +$tb {security-type} $br +$tb {parallel-type} $br + +$tb [COST ] {execution-cost} $br + +%if {returns-setof} %then + $tb [ROWS ] {row-amount} $br +%end + +%if {config-params} %then + {config-params} +%end + +$tb [AS ] + +%if {library} %then + '{library}' + + %if {symbol} %then + [, ] '{symbol}' + %end +%else + %if ({language} == "internal") %then + '{definition}' + %else + [$$] + + $br {definition} $br + [$$] + %end +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/genericsql.sch b/assets/schemas/sql/genericsql.sch new file mode 100644 index 0000000000..3e889437f3 --- /dev/null +++ b/assets/schemas/sql/genericsql.sch @@ -0,0 +1,13 @@ +# SQL definition for generic sql objects +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: Generic SQL Object --] $br + +{definition} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +$br [-- ddl-end --] $br + +$br diff --git a/assets/schemas/sql/idxelement.sch b/assets/schemas/sql/idxelement.sch new file mode 100644 index 0000000000..66d5bf4946 --- /dev/null +++ b/assets/schemas/sql/idxelement.sch @@ -0,0 +1,34 @@ +# SQL definition for index elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$br $tb + +%if {column} %then + {column} +%else + %if {expression} %then + ({expression}) + %end +%end + +%if {collation} %then + [ COLLATE ] {collation} +%end + +%if {opclass} %then + $sp {opclass} +%end + +%if {use-sorting} %then + %if {asc-order} %then + [ ASC ] + %else + [ DESC ] + %end + + %if {nulls-first} %then + [NULLS FIRST] + %else + [NULLS LAST] + %end +%end diff --git a/assets/schemas/sql/index.sch b/assets/schemas/sql/index.sch new file mode 100644 index 0000000000..e24c114c5c --- /dev/null +++ b/assets/schemas/sql/index.sch @@ -0,0 +1,78 @@ +# SQL definition for indexes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ] %if {unique} %then [UNIQUE ] %end [INDEX ] + +%if {concurrent} %then + [ CONCURRENTLY ] +%end + +{name} [ ON ] {table} + +%if {index-type} %then + $br [USING ] {index-type} +%end + +$br ( {elements} $br ) + +%if {expression} %then + $br ({expression}) $sp +%end + +%if ({pgsql-ver} >=f "11.0") %and {include-cols} %then + $br [INCLUDE ] ({include-cols}) +%end + +%if {stg-params} %then + $br [WITH (] + + %if {factor} %then + [FILLFACTOR = ] {factor} + %end + + %if {fast-update} %then + %if {factor} %then [, ] %end + [FASTUPDATE = ON] + %end + + %if {buffering} %then + %if {factor} %then [, ] %end + [BUFFERING = ON] + %end + + [)] +%end + +%if {tablespace} %then + $br [TABLESPACE ] {tablespace} +%end + +%if {predicate} %then + $br [WHERE (] {predicate} [)] +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/language.sch b/assets/schemas/sql/language.sch new file mode 100644 index 0000000000..7c50ea7f69 --- /dev/null +++ b/assets/schemas/sql/language.sch @@ -0,0 +1,52 @@ +# SQL definition for procedural languages +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ] + +%if {trusted} %then + + %if {handler} %then + [TRUSTED ] + %end +%end + +[ LANGUAGE ] {name} + +%if {handler} %then + $br $tb [HANDLER ] {handler} +%end + +%if {validator} %then + $br [VALIDATOR ] {validator} +%end + +%if {inline} %then + $br [INLINE ] {inline} +%end + +; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/opclass.sch b/assets/schemas/sql/opclass.sch new file mode 100644 index 0000000000..f078ed7f11 --- /dev/null +++ b/assets/schemas/sql/opclass.sch @@ -0,0 +1,38 @@ +# SQL definition for operator classes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE OPERATOR CLASS ] {name} +%if {default} %then [ DEFAULT ] %end + +[ FOR TYPE ] {type} $br +[ USING ] {index-type} + +%if {family} %then [ FAMILY ] {family} %end +[ AS] $br + +{elements}; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/operator.sch b/assets/schemas/sql/operator.sch new file mode 100644 index 0000000000..96c87cc5ca --- /dev/null +++ b/assets/schemas/sql/operator.sch @@ -0,0 +1,65 @@ +# SQL definition for operators +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE OPERATOR ] {name} [ (] + +$br $tb [PROCEDURE = ] {operfunc} + +%if {left-type} %then + $br $tb [, LEFTARG = ] {left-type} +%end + +%if {right-type} %then + $br $tb [, RIGHTARG = ] {right-type} +%end + +%if {commutator-op} %then + $br $tb [, COMMUTATOR = ] OPERATOR({commutator-op}) +%end + +%if {negator-op} %then + $br $tb [, NEGATOR = ] OPERATOR({negator-op}) +%end + +%if {restriction} %then + $br $tb [, RESTRICT = ] {restriction} +%end + +%if {join} %then + $br $tb [, JOIN = ] {join} +%end + +%if {hashes} %then + $br $tb [, HASHES ] +%end + +%if {merges} %then + $br $tb [, MERGES ] +%end + +); + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/opfamily.sch b/assets/schemas/sql/opfamily.sch new file mode 100644 index 0000000000..b164024db6 --- /dev/null +++ b/assets/schemas/sql/opfamily.sch @@ -0,0 +1,29 @@ +# SQL definition for operator family +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE OPERATOR FAMILY ] {name} [ USING ] {index-type}; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/parameter.sch b/assets/schemas/sql/parameter.sch new file mode 100644 index 0000000000..1c0e958320 --- /dev/null +++ b/assets/schemas/sql/parameter.sch @@ -0,0 +1,22 @@ +# SQL definition for function parameters +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {variadic} %then + VARIADIC $sp +%else + %if {in} %then IN $sp %end + %if {out} %then OUT $sp %end +%end + +%if {reduced-form} %then + {type}, $sp +%else + {name} $sp {type} + + %if {default-value} %then + [ DEFAULT ] {default-value} + %end + + , $sp +%end diff --git a/assets/schemas/sql/partitionkey.sch b/assets/schemas/sql/partitionkey.sch new file mode 100644 index 0000000000..ef28c88691 --- /dev/null +++ b/assets/schemas/sql/partitionkey.sch @@ -0,0 +1,19 @@ +# SQL definition for partition key elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {column} %then + {column} +%else + %if {expression} %then + ({expression}) + %end +%end + +%if {collation} %then + [ COLLATE ] {collation} +%end + +%if {opclass} %then + $sp {opclass} +%end diff --git a/assets/schemas/sql/permission.sch b/assets/schemas/sql/permission.sch new file mode 100644 index 0000000000..8fecaf6785 --- /dev/null +++ b/assets/schemas/sql/permission.sch @@ -0,0 +1,71 @@ +# SQL definition for permissions on objects +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] PERMISSION [ --] + +%if {privileges} %then + + $br + + %if {revoke} %then + [REVOKE ] + %else + [GRANT ] + %end + + {privileges} $br + + %if {parent} %then + $sp $sp [ ON TABLE ] {parent} $br + %else + $sp $sp [ ON ] {type} $sp {object} $br + %end + + $sp $sp %if {revoke} %then [ FROM ] %else [ TO ] %end + + %if {roles} %then + {roles} + + %if {revoke} %and {cascade} %then + [ CASCADE] + %end + %else + PUBLIC + %end + + ; $br +%end + + +%if {privileges-gop} %then + + $br + + %if {revoke} %then + [REVOKE GRANT OPTION FOR ] + %else + [GRANT ] + %end + + {privileges-gop} $br + + %if {parent} %then + $sp $sp [ ON TABLE ] {parent} $br + %else + $sp $sp [ ON ] {type} $sp {object} $br + %end + + $sp $sp + + %if {revoke} %then + [ FROM ] {roles} + %if {cascade} %then [ CASCADE] %end ; $br + %else + [ TO ] {roles} [ WITH GRANT OPTION]; $br + %end +%end + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +[-- ddl-end --] $br $br diff --git a/assets/schemas/sql/policy.sch b/assets/schemas/sql/policy.sch new file mode 100644 index 0000000000..bf40215f5d --- /dev/null +++ b/assets/schemas/sql/policy.sch @@ -0,0 +1,53 @@ +# SQL definition for policy +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE POLICY ] {name} [ ON ] {table} + +%if {permissive} %then + $br $tb [AS PERMISSIVE] +%else + $br $tb [AS RESTRICTIVE] +%end + +$br $tb [FOR ] {command} +$br $tb [TO ] + +%if {roles} %then + {roles} +%else + PUBLIC +%end + +%if {using-exp} %then + $br $tb [USING (] {using-exp} [)] +%end + +%if {check-exp} %then + $br $tb [WITH CHECK (] {check-exp} [)] +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/procedure.sch b/assets/schemas/sql/procedure.sch new file mode 100644 index 0000000000..3dc11e494b --- /dev/null +++ b/assets/schemas/sql/procedure.sch @@ -0,0 +1,59 @@ +# SQL definition for procedures +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if ({pgsql-ver} >=f "11.0") %then + [-- object: ] {name} [ | type: ] {sql-object} [ --] $br + [-- ] {drop} + + # This is a special token that pgModeler recognizes as end of DDL command + # when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! + %set {ddl-end} $br [-- ddl-end --] $br + + %if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br + %end + + [CREATE PROCEDURE ] {name} $sp ( %if {parameters} %then {parameters} %end ) $br + $tb [LANGUAGE ] {language} $br + + %if {transform-types} %then + $tb TRANSFORM {transform-types} $br + %end + + $tb {security-type} $br + + %if {config-params} %then + {config-params} + %end + + $tb [AS ] + + %if {library} %then + '{library}' + + %if {symbol} %then + [, ] '{symbol}' + %end + %else + [$$] + + $br {definition} $br + [$$] + %end + + ; + + {ddl-end} + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + + %if {appended-sql} %then + {appended-sql} + {ddl-end} + %end + + $br +%end diff --git a/assets/schemas/sql/relationship.sch b/assets/schemas/sql/relationship.sch new file mode 100644 index 0000000000..ae16320a6a --- /dev/null +++ b/assets/schemas/sql/relationship.sch @@ -0,0 +1,17 @@ +# SQL definition for relationships +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {rel1n} %then + {constraints} +%end + +#%if {relgen} %then +# [ALTER TABLE ] {table} [ INHERIT ] {ancestor-table}; $br $br +#%end + +%if {relnn} %then + {table} + {constraints} +%end + diff --git a/assets/schemas/sql/role.sch b/assets/schemas/sql/role.sch new file mode 100644 index 0000000000..e7c7db22f2 --- /dev/null +++ b/assets/schemas/sql/role.sch @@ -0,0 +1,44 @@ +# SQL definition for type roles +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ROLE ] {name} [ WITH ] + +%if {superuser} %then $br $tb SUPERUSER %end +%if {createdb} %then $br $tb CREATEDB %end +%if {createrole} %then $br $tb CREATEROLE %end +%if {inherit} %then $br $tb INHERIT %end +%if {login} %then $br $tb LOGIN %end +%if {replication} %then $br $tb REPLICATION %end +%if {bypassrls} %then $br $tb BYPASSRLS %end + +%if {password} %then $br $tb [ PASSWORD ] '{password}' %end +%if {connlimit} %then $br $tb [CONNECTION LIMIT ] {connlimit} %end +%if {validity} %then $br $tb [VALID UNTIL ] '{validity}' %end + +%if {member-roles} %then $br $tb [ROLE ] {member-roles} %end +%if {admin-roles} %then $br $tb [ADMIN ] {admin-roles} %end +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/rule.sch b/assets/schemas/sql/rule.sch new file mode 100644 index 0000000000..49f30926c7 --- /dev/null +++ b/assets/schemas/sql/rule.sch @@ -0,0 +1,43 @@ +# SQL definition for rules +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE RULE ] {name} [ AS ] {event-type} $br +$tb [TO ] {table} $br + +%if {condition} %then + $tb [WHERE ] {condition} $br +%end + +$tb [DO ] {exec-type} $sp + +%if {commands} %then + ({commands}) +%else + NOTHING +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/schema.sch b/assets/schemas/sql/schema.sch new file mode 100644 index 0000000000..8eec1257f8 --- /dev/null +++ b/assets/schemas/sql/schema.sch @@ -0,0 +1,29 @@ +# SQL definition for schemas +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE SCHEMA ] {name}; + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/sequence.sch b/assets/schemas/sql/sequence.sch new file mode 100644 index 0000000000..3ea2b13772 --- /dev/null +++ b/assets/schemas/sql/sequence.sch @@ -0,0 +1,67 @@ +# SQL definition for sequences +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE SEQUENCE ] {name} $br + +%if {increment} %then + $tb [INCREMENT BY ] {increment} $br +%end + +%if {min-value} %then + $tb [MINVALUE ] {min-value} $br +%end + +%if {max-value} %then + $tb [MAXVALUE ] {max-value} $br +%end + +%if {start} %then + $tb [START WITH ] {start} $br +%end + +%if {cache} %then + $tb [CACHE ] {cache} $br +%end + +%if {cycle} %then + $tb CYCLE +%else + $tb [NO CYCLE] +%end + +$br + +$tb [OWNED BY ] +%if {owner-col} %then {owner-col} %else NONE %end +; $br + +%if {owner-col} %and %not {col-is-identity} %then + $br + [ALTER TABLE ] {table} [ ALTER COLUMN ] {column} $br + [ SET DEFAULT nextval('] {name} ['::regclass);] +%end + +{ddl-end} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/sessionopts.sch b/assets/schemas/sql/sessionopts.sch new file mode 100644 index 0000000000..f6e6a32060 --- /dev/null +++ b/assets/schemas/sql/sessionopts.sch @@ -0,0 +1,13 @@ +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {function} %then + [SET check_function_bodies = false;] + {ddl-end} $br +%end + +%if {search-path} %then + [SET search_path TO ] {search-path}; + {ddl-end} $br +%end diff --git a/assets/schemas/sql/table.sch b/assets/schemas/sql/table.sch new file mode 100644 index 0000000000..d284ec53b2 --- /dev/null +++ b/assets/schemas/sql/table.sch @@ -0,0 +1,142 @@ +# SQL definition for tables +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE] + +%if {unlogged} %then + [ UNLOGGED] +%end + +[ TABLE ] {name} + +%if {partitioned-table} %then + $br [PARTITION OF ] {partitioned-table} $sp +%end + +%if %not {partitioned-table} %then + + [ (] $br + + %if {copy-table} %then + $tb LIKE $sp {copy-table} + + %if %not {gen-alter-cmds} %then + %if {columns} %or {constraints} %then + [,] + %end + %end + + $br + %end + + %if %not {gen-alter-cmds} %then + %if {columns} %then + {columns} + %end + + %if {inh-columns} %then + {inh-columns} + %end + + %if {constraints} %then + {constraints} + %end + %end + + + %if %not {constraints} %then + $br + %end + + ) +%else + %if %not {gen-alter-cmds} %and {partitioned-table} %and {constraints} %then + [ (] $br {constraints} $br [)] + %end +%end + +%if {partitioned-table} %then + %if {partition-bound-expr} %then + $br [FOR VALUES ] {partition-bound-expr} + %else + DEFAULT + %end +%end + +%if {partitioning} %then + $br [PARTITION BY ] {partitioning} [ (] {partitionkey} [)] +%end + +%if {ancestor-table} %then + $br [ INHERITS(] {ancestor-table} [)] +%end + +%if ({pgsql-ver} <=f "11.0") %and {oids} %then + $br [WITH ( OIDS = TRUE )] +%end + +%if {tablespace} %then + $br [TABLESPACE ] {tablespace} +%end + +; + +{ddl-end} + +%if {gen-alter-cmds} %then + %if {columns} %then + $br {columns} + %end + + %if {constraints} %then + $br {constraints} + %end +%end + +%if {comment} %then + {comment} +%end + +%if {cols-comment} %then + {cols-comment} +%end + +%if {owner} %then + {owner} +%end + +%if {rls-enabled} %then + [ALTER TABLE ] {name} [ ENABLE ROW LEVEL SECURITY;] + + {ddl-end} + + %if {rls-forced} %then + [ALTER TABLE ] {name} [ FORCE ROW LEVEL SECURITY;] + + {ddl-end} + %end +%end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +%if {initial-data} %then + $br {initial-data} $br +%end + +$br diff --git a/assets/schemas/sql/tablespace.sch b/assets/schemas/sql/tablespace.sch new file mode 100644 index 0000000000..c651b84514 --- /dev/null +++ b/assets/schemas/sql/tablespace.sch @@ -0,0 +1,34 @@ +# SQL definition for tablespaces +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE TABLESPACE ] {name} $br + +%if {owner} %then + $tb [OWNER ] {owner} $br +%end + +$tb [LOCATION ] {directory}; $br + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/transform.sch b/assets/schemas/sql/transform.sch new file mode 100644 index 0000000000..30e7dbdb0b --- /dev/null +++ b/assets/schemas/sql/transform.sch @@ -0,0 +1,46 @@ +# SQL definition for transforms +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE TRANSFORM FOR ] {type} [ LANGUAGE ] {language} [ (] + +# One of the two function should be defined otherwise the code generation will fail + +%if {fromsql} %or %not {tosql} %then + $br $tb [FROM SQL WITH FUNCTION ] {fromsql} +%end + +%if {fromsql} %and {tosql} %then + , +%end + +%if {tosql} %or %not {fromsql} %then + $br $tb [TO SQL WITH FUNCTION ] {tosql} +%end + +$br [);] + +{ddl-end} + +%if {comment} %then + {comment} +%end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/trigger.sch b/assets/schemas/sql/trigger.sch new file mode 100644 index 0000000000..cff146c43b --- /dev/null +++ b/assets/schemas/sql/trigger.sch @@ -0,0 +1,59 @@ +# SQL definition for triggers +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ] +%if {constraint} %then [CONSTRAINT ]%end +[TRIGGER ] {name} $br +$tb {firing-type} $sp {events} $br + +$tb [ON ] {table} $br + +%if {constraint} %then + %if {ref-table} %then + $tb [FROM ] {ref-table} $br + %end + + %if {deferrable} %then + $tb [DEFERRABLE ] {defer-type} $br + %else + $tb [NOT DEFERRABLE ] $br + %end +%end + +%if {old-table-name} %or {new-table-name} %then + $tb REFERENCING + %if {old-table-name} %then [ OLD TABLE AS ] {old-table-name} %end + %if {new-table-name} %then [ NEW TABLE AS ] {new-table-name} %end + $br +%end + +$tb [FOR EACH ] %if {per-line} %then ROW %else STATEMENT %end $br + +%if {condition} %then $tb WHEN $sp ({condition}) $br %end + +$tb [EXECUTE PROCEDURE ] {trigger-func}( +%if {arguments} %then {arguments} %end ); + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/typeattribute.sch b/assets/schemas/sql/typeattribute.sch new file mode 100644 index 0000000000..ea66dd2070 --- /dev/null +++ b/assets/schemas/sql/typeattribute.sch @@ -0,0 +1,10 @@ +# SQL definition for user defined type attributes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ ] {name} $sp {type} + +%if {collation} %then + [ COLLATE ] {collation} +%end + +, $br diff --git a/assets/schemas/sql/usermapping.sch b/assets/schemas/sql/usermapping.sch new file mode 100644 index 0000000000..649dd34de7 --- /dev/null +++ b/assets/schemas/sql/usermapping.sch @@ -0,0 +1,38 @@ +# SQL definition for user mapping +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE USER MAPPING FOR ] + +%if {owner} %then {owner} %else PUBLIC %end $br + +[SERVER ] {server} + +%if {options} %then + $br [OPTIONS (] {options} ) +%end + +; + +{ddl-end} + +%if {comment} %then {comment} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/sql/usertype.sch b/assets/schemas/sql/usertype.sch new file mode 100644 index 0000000000..7315321cde --- /dev/null +++ b/assets/schemas/sql/usertype.sch @@ -0,0 +1,86 @@ +# SQL definition for user defined types +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +[CREATE TYPE ] {name} + +%if {reduced-form} %then + ; {ddl-end} $br +%else + %if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br + %end + + %if {base} %then + [ (] $br + %else + [ AS] $br + %end + + %if {composite} %then + ( $br {typeattrib} $br ); + %end + + %if {enumeration} %then + [ENUM ] ( + %if {labels} %then {labels} %end + [);] + %end + + %if {range} %then + [RANGE (] $br + [SUBTYPE = ] {subtype} + + %if {collation} %then $br [, COLLATE = ] {collation} %end + %if {opclass} %then $br [, SUBTYPE_OPCLASS = ] {opclass} %end + %if {canonical} %then $br [, CANONICAL = ] {canonical} %end + %if {subtypediff} %then $br [, SUBTYPE_DIFF = ] {subtypediff} %end + + ); + %end + + %if {base} %then + %if {input} %then $tb [INPUT = ] {input}, $br %end + %if {output} %then $tb [OUTPUT = ] {output} $br %end + %if {receive} %then $tb [, RECEIVE = ] {receive} $br %end + %if {send} %then $tb [, SEND = ] {send} $br %end + %if {tpmodin} %then $tb [, TYPMOD_IN = ] {tpmodin} $br %end + %if {tpmodout} %then $tb [, TYPMOD_OUT = ] {tpmodout} $br %end + %if {analyze} %then $tb [, ANALYZE = ] {analyze} $br %end + %if {internal-length} %then $tb [, INTERNALLENGTH = ] {internal-length} $br %end + %if {by-value} %then $tb [, PASSEDBYVALUE ] $br %end + %if {alignment} %then $tb [, ALIGNMENT = ] {alignment} $br %end + %if {storage} %then $tb [, STORAGE = ] {storage} $br %end + %if {default-value} %then $tb [, DEFAULT = ] {default-value} $br %end + %if {element} %then $tb [, ELEMENT = ] {element} $br %end + %if {delimiter} %then $tb [, DELIMITER = ] '{delimiter}' $br %end + %if {like-type} %then $tb [, LIKE = ] {like-type} $br %end + %if {category} %then $tb [, CATEGORY = ] '{category}' $br %end + %if {preferred} %then $tb [, PREFERRED = ] true $br %end + %if {collatable} %then $tb [, COLLATABLE = ] true $br %end + + ); + %end + + {ddl-end} + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + + %if {appended-sql} %then + {appended-sql} + {ddl-end} + %end + + $br +%end + + diff --git a/assets/schemas/sql/view.sch b/assets/schemas/sql/view.sch new file mode 100644 index 0000000000..2d46cea5cc --- /dev/null +++ b/assets/schemas/sql/view.sch @@ -0,0 +1,63 @@ +# SQL definition for views +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[-- object: ] {name} [ | type: ] {sql-object} [ --] $br +[-- ] {drop} + +# This is a special token that pgModeler recognizes as end of DDL command +# when exporting models directly to DBMS. DO NOT REMOVE THIS TOKEN! +%set {ddl-end} $br [-- ddl-end --] $br + +%if {prepended-sql} %then + {prepended-sql} + {ddl-end} $br +%end + +[CREATE ] + +%if {recursive} %then + [RECURSIVE ] +%else + %if {materialized} %then + [MATERIALIZED ] + %end +%end + +VIEW $sp {name} + +%if {columns} %then + [ (] {columns} [)] +%end + +$br + +%if {materialized} %and {tablespace} %then + TABLESPACE $sp {tablespace} $br +%end + +[AS ] $br + +#Commom table expression (CTE) +%if {cte-exp} %then + [WITH ] {cte-exp} +%end + +$br {definition} + +%if {materialized} %and {with-no-data} %then + $br [WITH NO DATA;] +%end + + +{ddl-end} + +%if {comment} %then {comment} %end +%if {owner} %then {owner} %end + +%if {appended-sql} %then + {appended-sql} + {ddl-end} +%end + +$br diff --git a/assets/schemas/xml/aggregate.sch b/assets/schemas/xml/aggregate.sch new file mode 100644 index 0000000000..d7031397ff --- /dev/null +++ b/assets/schemas/xml/aggregate.sch @@ -0,0 +1,31 @@ +# XML definition for aggregate functions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br +{schema} +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +%if {types} %then {types} %end + +{state-type} +{transition} +%if {final} %then {final} %end +%if {sort-op} %then {sort-op} %end + $br $br diff --git a/assets/schemas/xml/appendedsql.sch b/assets/schemas/xml/appendedsql.sch new file mode 100644 index 0000000000..c9fac7f519 --- /dev/null +++ b/assets/schemas/xml/appendedsql.sch @@ -0,0 +1,9 @@ +# XML definition for appendend SQL commands +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +#Creates element envolving the appended-sql +#The tag is converted to in order +#to not cause syntax errors on the schema parser + +$tb $sp $sp $br diff --git a/assets/schemas/xml/basetype.sch b/assets/schemas/xml/basetype.sch new file mode 100644 index 0000000000..c4934b45cb --- /dev/null +++ b/assets/schemas/xml/basetype.sch @@ -0,0 +1,36 @@ +# XML definition for native types +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb [ $br diff --git a/assets/schemas/xml/cast.sch b/assets/schemas/xml/cast.sch new file mode 100644 index 0000000000..c9cc112517 --- /dev/null +++ b/assets/schemas/xml/cast.sch @@ -0,0 +1,33 @@ +# XML definition for type casts +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +{source-type} +{destiny-type} + +%if {function} %then {function} %end + + $br $br diff --git a/assets/schemas/xml/changelog.sch b/assets/schemas/xml/changelog.sch new file mode 100644 index 0000000000..bcc0697051 --- /dev/null +++ b/assets/schemas/xml/changelog.sch @@ -0,0 +1,9 @@ +# XML definition for database model changelog +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {entry} %then + $br + {entry} + $br $br +%end diff --git a/assets/schemas/xml/collation.sch b/assets/schemas/xml/collation.sch new file mode 100644 index 0000000000..5e01274490 --- /dev/null +++ b/assets/schemas/xml/collation.sch @@ -0,0 +1,34 @@ +# XML definition for collations +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {reduced-form} %then $tb %end + + $br + + %if {schema} %then {schema} %end + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + + +%else + /> $br +%end diff --git a/assets/schemas/xml/column.sch b/assets/schemas/xml/column.sch new file mode 100644 index 0000000000..3f20444f48 --- /dev/null +++ b/assets/schemas/xml/column.sch @@ -0,0 +1,52 @@ +# XML definition for columns +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb [ $br + +$tb {type} + +%if {comment} %then $tb {comment} %end + +$tb $br diff --git a/assets/schemas/xml/comment.sch b/assets/schemas/xml/comment.sch new file mode 100644 index 0000000000..7c3c1015e8 --- /dev/null +++ b/assets/schemas/xml/comment.sch @@ -0,0 +1,9 @@ +# XML definition for comments +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +#Creates element envolving the comment +#The tag is converted to in order +#to not cause syntax errors on the schema parser + +$tb $sp $sp $br \ No newline at end of file diff --git a/assets/schemas/xml/confparam.sch b/assets/schemas/xml/confparam.sch new file mode 100644 index 0000000000..49e5185c97 --- /dev/null +++ b/assets/schemas/xml/confparam.sch @@ -0,0 +1,5 @@ +# XML definition for functions/procedures configuration parameters definition +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb $br diff --git a/assets/schemas/xml/constraint.sch b/assets/schemas/xml/constraint.sch new file mode 100644 index 0000000000..9c8839dea1 --- /dev/null +++ b/assets/schemas/xml/constraint.sch @@ -0,0 +1,83 @@ +# XML definition for constraints +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {decl-in-table} %then $tb %end + +[ $br + +%if {tablespace} %then $tb {tablespace} %end + +%if {decl-in-table} %then $tb %end + +%if {src-columns} %then + $tb $br +%end + +%if {dst-columns} %then + %if {decl-in-table} %then $tb %end + $tb $br +%end + +%if {ex-constr} %then + {elements} +%end + +%if {ck-constr} %or {ex-constr} %then + %if {expression} %then + %if {decl-in-table} %then $tb %end + $tb $sp $sp $br + %end +%end + +%if {comment} %then $tb {comment} %end + +%if {decl-in-table} %then $tb %end + $br +%if %not {decl-in-table} %then $br %end diff --git a/assets/schemas/xml/conversion.sch b/assets/schemas/xml/conversion.sch new file mode 100644 index 0000000000..990854c5de --- /dev/null +++ b/assets/schemas/xml/conversion.sch @@ -0,0 +1,30 @@ +# XML definition for type encoding conversion +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +{schema} +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +{function} + + $br $br diff --git a/assets/schemas/xml/customidxs.sch b/assets/schemas/xml/customidxs.sch new file mode 100644 index 0000000000..ff20ceece3 --- /dev/null +++ b/assets/schemas/xml/customidxs.sch @@ -0,0 +1,6 @@ +# XML definition for custom object indexes in tables +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$br $tb [ $br +{objects} +$tb diff --git a/assets/schemas/xml/database.sch b/assets/schemas/xml/database.sch new file mode 100644 index 0000000000..bfcf590411 --- /dev/null +++ b/assets/schemas/xml/database.sch @@ -0,0 +1,34 @@ +# XML definition for tablespaces +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +%if {owner} %then {owner} %end +%if {tablespace} %then {tablespace} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + + $br $br diff --git a/assets/schemas/xml/dbmodel.sch b/assets/schemas/xml/dbmodel.sch new file mode 100644 index 0000000000..9bc990edbd --- /dev/null +++ b/assets/schemas/xml/dbmodel.sch @@ -0,0 +1,80 @@ +# XML definition for database model +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + $br +[] $br + $br +%if {objects} %then {objects} %end +%if {permission} %then {permission} %end +%if {changelog} %then {changelog} %end + $br diff --git a/assets/schemas/xml/domain.sch b/assets/schemas/xml/domain.sch new file mode 100644 index 0000000000..1c2a18c3c2 --- /dev/null +++ b/assets/schemas/xml/domain.sch @@ -0,0 +1,41 @@ +# XML definition for domains +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br +%else + + #%if {constraint} %then + # [ constraint=] "{constraint}" + #%end + + [ not-null=] %if {not-null} %then "true" %else "false" %end + %if {default-value} %then [ default-value=] "&{default-value}" %end + + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + {schema} + %if {owner} %then {owner} %end + %if {collation} %then {collation} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + {type} + + %if {constraints} %then + {constraints} + %end + + $br $br +%end diff --git a/assets/schemas/xml/domconstraint.sch b/assets/schemas/xml/domconstraint.sch new file mode 100644 index 0000000000..1eb8adccda --- /dev/null +++ b/assets/schemas/xml/domconstraint.sch @@ -0,0 +1,8 @@ +# XML definition for domain's check constraint +# PostgreSQL Version: 9.x +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb [] $br +$tb $tb $sp $sp $br +$tb [] $br diff --git a/schemas/xml/dtd/aggregate.dtd b/assets/schemas/xml/dtd/aggregate.dtd similarity index 100% rename from schemas/xml/dtd/aggregate.dtd rename to assets/schemas/xml/dtd/aggregate.dtd diff --git a/schemas/xml/dtd/baseelements.dtd b/assets/schemas/xml/dtd/baseelements.dtd similarity index 80% rename from schemas/xml/dtd/baseelements.dtd rename to assets/schemas/xml/dtd/baseelements.dtd index 9b963d26ce..41d2366878 100644 --- a/schemas/xml/dtd/baseelements.dtd +++ b/assets/schemas/xml/dtd/baseelements.dtd @@ -23,3 +23,10 @@ + + + + + + + diff --git a/schemas/xml/dtd/basetype.dtd b/assets/schemas/xml/dtd/basetype.dtd similarity index 100% rename from schemas/xml/dtd/basetype.dtd rename to assets/schemas/xml/dtd/basetype.dtd diff --git a/schemas/xml/dtd/cast.dtd b/assets/schemas/xml/dtd/cast.dtd similarity index 100% rename from schemas/xml/dtd/cast.dtd rename to assets/schemas/xml/dtd/cast.dtd diff --git a/assets/schemas/xml/dtd/changelog.dtd b/assets/schemas/xml/dtd/changelog.dtd new file mode 100644 index 0000000000..2b44a79887 --- /dev/null +++ b/assets/schemas/xml/dtd/changelog.dtd @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/assets/schemas/xml/dtd/collation.dtd b/assets/schemas/xml/dtd/collation.dtd new file mode 100644 index 0000000000..7a067b87be --- /dev/null +++ b/assets/schemas/xml/dtd/collation.dtd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/assets/schemas/xml/dtd/column.dtd b/assets/schemas/xml/dtd/column.dtd new file mode 100644 index 0000000000..0a8fde39b1 --- /dev/null +++ b/assets/schemas/xml/dtd/column.dtd @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/schemas/xml/dtd/constraint.dtd b/assets/schemas/xml/dtd/constraint.dtd similarity index 96% rename from schemas/xml/dtd/constraint.dtd rename to assets/schemas/xml/dtd/constraint.dtd index be1946fbdb..55588c535c 100644 --- a/schemas/xml/dtd/constraint.dtd +++ b/assets/schemas/xml/dtd/constraint.dtd @@ -4,6 +4,7 @@ --> + diff --git a/schemas/xml/dtd/conversion.dtd b/assets/schemas/xml/dtd/conversion.dtd similarity index 100% rename from schemas/xml/dtd/conversion.dtd rename to assets/schemas/xml/dtd/conversion.dtd diff --git a/schemas/xml/dtd/customidxs.dtd b/assets/schemas/xml/dtd/customidxs.dtd similarity index 100% rename from schemas/xml/dtd/customidxs.dtd rename to assets/schemas/xml/dtd/customidxs.dtd diff --git a/schemas/xml/dtd/database.dtd b/assets/schemas/xml/dtd/database.dtd similarity index 100% rename from schemas/xml/dtd/database.dtd rename to assets/schemas/xml/dtd/database.dtd diff --git a/assets/schemas/xml/dtd/dbmodel.dtd b/assets/schemas/xml/dtd/dbmodel.dtd new file mode 100644 index 0000000000..3d3ce36055 --- /dev/null +++ b/assets/schemas/xml/dtd/dbmodel.dtd @@ -0,0 +1,105 @@ + + +%baseelements; + +%basetype; + +%object; + +%role; + +%tablespace; + +%database; + +%schema; + +%language; + +%parameter; + +%function; + +%usertype; + +%cast; + +%conversion; + +%operator; + +%opfamily; + +%opclass; + +%aggregate; + +%domain; + +%index; + +%rule; + +%trigger; + +%table; + +%sequence; + +%view; + +%textbox; + +%relationship; + +%permission; + +%collation; + +%extension; + +%tag; + +%customidxs; + +%eventtrigger; + +%genericsql; + +%policy; + +%foreigndatawrapper; + +%foreignserver; + +%usermapping; + +%foreigntable; + +%transform; + +%procedure; + +%changelog; + + + + + + + + + + + + + + + + + + + diff --git a/schemas/xml/dtd/domain.dtd b/assets/schemas/xml/dtd/domain.dtd similarity index 100% rename from schemas/xml/dtd/domain.dtd rename to assets/schemas/xml/dtd/domain.dtd diff --git a/schemas/xml/dtd/element.dtd b/assets/schemas/xml/dtd/element.dtd similarity index 100% rename from schemas/xml/dtd/element.dtd rename to assets/schemas/xml/dtd/element.dtd diff --git a/schemas/xml/dtd/eventtrigger.dtd b/assets/schemas/xml/dtd/eventtrigger.dtd similarity index 100% rename from schemas/xml/dtd/eventtrigger.dtd rename to assets/schemas/xml/dtd/eventtrigger.dtd diff --git a/schemas/xml/dtd/extension.dtd b/assets/schemas/xml/dtd/extension.dtd similarity index 100% rename from schemas/xml/dtd/extension.dtd rename to assets/schemas/xml/dtd/extension.dtd diff --git a/assets/schemas/xml/dtd/foreigndatawrapper.dtd b/assets/schemas/xml/dtd/foreigndatawrapper.dtd new file mode 100644 index 0000000000..78b4689c6e --- /dev/null +++ b/assets/schemas/xml/dtd/foreigndatawrapper.dtd @@ -0,0 +1,9 @@ + + + + + + diff --git a/assets/schemas/xml/dtd/foreignserver.dtd b/assets/schemas/xml/dtd/foreignserver.dtd new file mode 100644 index 0000000000..b9abb46e87 --- /dev/null +++ b/assets/schemas/xml/dtd/foreignserver.dtd @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/assets/schemas/xml/dtd/foreigntable.dtd b/assets/schemas/xml/dtd/foreigntable.dtd new file mode 100644 index 0000000000..647ef0e08e --- /dev/null +++ b/assets/schemas/xml/dtd/foreigntable.dtd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/schemas/xml/dtd/function.dtd b/assets/schemas/xml/dtd/function.dtd new file mode 100644 index 0000000000..180e0fcea1 --- /dev/null +++ b/assets/schemas/xml/dtd/function.dtd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/schemas/xml/dtd/genericsql.dtd b/assets/schemas/xml/dtd/genericsql.dtd similarity index 88% rename from schemas/xml/dtd/genericsql.dtd rename to assets/schemas/xml/dtd/genericsql.dtd index 40ec0a02f5..f1a1c8ea5a 100644 --- a/schemas/xml/dtd/genericsql.dtd +++ b/assets/schemas/xml/dtd/genericsql.dtd @@ -2,7 +2,7 @@ CAUTION: Do not modify this file directly on it's code unless you know what you are doing. Unexpected results may occur if the code is changed deliberately. --> - + diff --git a/schemas/xml/dtd/index.dtd b/assets/schemas/xml/dtd/index.dtd similarity index 92% rename from schemas/xml/dtd/index.dtd rename to assets/schemas/xml/dtd/index.dtd index f7d02fe9e3..4f6da04967 100644 --- a/schemas/xml/dtd/index.dtd +++ b/assets/schemas/xml/dtd/index.dtd @@ -1,9 +1,10 @@ - - + + diff --git a/schemas/xml/dtd/label.dtd b/assets/schemas/xml/dtd/label.dtd similarity index 100% rename from schemas/xml/dtd/label.dtd rename to assets/schemas/xml/dtd/label.dtd diff --git a/schemas/xml/dtd/language.dtd b/assets/schemas/xml/dtd/language.dtd similarity index 100% rename from schemas/xml/dtd/language.dtd rename to assets/schemas/xml/dtd/language.dtd diff --git a/assets/schemas/xml/dtd/metadata.dtd b/assets/schemas/xml/dtd/metadata.dtd new file mode 100644 index 0000000000..5dc502ee98 --- /dev/null +++ b/assets/schemas/xml/dtd/metadata.dtd @@ -0,0 +1,57 @@ + + +%baseelements; + + +%label; + + +%textbox; + + +%tag; + + +%object; + + +%genericsql; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/schemas/xml/dtd/object.dtd b/assets/schemas/xml/dtd/object.dtd new file mode 100644 index 0000000000..2047dd8dc2 --- /dev/null +++ b/assets/schemas/xml/dtd/object.dtd @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/schemas/xml/dtd/opclass.dtd b/assets/schemas/xml/dtd/opclass.dtd similarity index 100% rename from schemas/xml/dtd/opclass.dtd rename to assets/schemas/xml/dtd/opclass.dtd diff --git a/schemas/xml/dtd/operator.dtd b/assets/schemas/xml/dtd/operator.dtd similarity index 100% rename from schemas/xml/dtd/operator.dtd rename to assets/schemas/xml/dtd/operator.dtd diff --git a/schemas/xml/dtd/opfamily.dtd b/assets/schemas/xml/dtd/opfamily.dtd similarity index 100% rename from schemas/xml/dtd/opfamily.dtd rename to assets/schemas/xml/dtd/opfamily.dtd diff --git a/assets/schemas/xml/dtd/parameter.dtd b/assets/schemas/xml/dtd/parameter.dtd new file mode 100644 index 0000000000..23c9c3c698 --- /dev/null +++ b/assets/schemas/xml/dtd/parameter.dtd @@ -0,0 +1,10 @@ + + + + + + + diff --git a/schemas/xml/dtd/permission.dtd b/assets/schemas/xml/dtd/permission.dtd similarity index 77% rename from schemas/xml/dtd/permission.dtd rename to assets/schemas/xml/dtd/permission.dtd index f7db5da3d0..a470a5c0ca 100644 --- a/schemas/xml/dtd/permission.dtd +++ b/assets/schemas/xml/dtd/permission.dtd @@ -21,10 +21,3 @@ - - - - - - - diff --git a/schemas/xml/dtd/policy.dtd b/assets/schemas/xml/dtd/policy.dtd similarity index 93% rename from schemas/xml/dtd/policy.dtd rename to assets/schemas/xml/dtd/policy.dtd index bc5c4d06b3..eba99706e2 100644 --- a/schemas/xml/dtd/policy.dtd +++ b/assets/schemas/xml/dtd/policy.dtd @@ -4,6 +4,7 @@ --> + diff --git a/assets/schemas/xml/dtd/procedure.dtd b/assets/schemas/xml/dtd/procedure.dtd new file mode 100644 index 0000000000..0a2df993bb --- /dev/null +++ b/assets/schemas/xml/dtd/procedure.dtd @@ -0,0 +1,10 @@ + + + + + + + diff --git a/schemas/xml/dtd/relationship.dtd b/assets/schemas/xml/dtd/relationship.dtd similarity index 92% rename from schemas/xml/dtd/relationship.dtd rename to assets/schemas/xml/dtd/relationship.dtd index 01baad3ad9..6e51e3216b 100644 --- a/schemas/xml/dtd/relationship.dtd +++ b/assets/schemas/xml/dtd/relationship.dtd @@ -5,11 +5,13 @@ %label; - + + + - + diff --git a/schemas/xml/dtd/role.dtd b/assets/schemas/xml/dtd/role.dtd similarity index 88% rename from schemas/xml/dtd/role.dtd rename to assets/schemas/xml/dtd/role.dtd index da52230792..9cbf9dd248 100644 --- a/schemas/xml/dtd/role.dtd +++ b/assets/schemas/xml/dtd/role.dtd @@ -1,4 +1,4 @@ - @@ -12,7 +12,6 @@ - @@ -20,4 +19,4 @@ - + diff --git a/schemas/xml/dtd/rule.dtd b/assets/schemas/xml/dtd/rule.dtd similarity index 93% rename from schemas/xml/dtd/rule.dtd rename to assets/schemas/xml/dtd/rule.dtd index a340b78336..0ce3103323 100644 --- a/schemas/xml/dtd/rule.dtd +++ b/assets/schemas/xml/dtd/rule.dtd @@ -4,6 +4,7 @@ --> + diff --git a/schemas/xml/dtd/schema.dtd b/assets/schemas/xml/dtd/schema.dtd similarity index 80% rename from schemas/xml/dtd/schema.dtd rename to assets/schemas/xml/dtd/schema.dtd index 8e17e3fc82..05eb223850 100644 --- a/schemas/xml/dtd/schema.dtd +++ b/assets/schemas/xml/dtd/schema.dtd @@ -1,11 +1,14 @@ - + + + diff --git a/schemas/xml/dtd/sequence.dtd b/assets/schemas/xml/dtd/sequence.dtd similarity index 100% rename from schemas/xml/dtd/sequence.dtd rename to assets/schemas/xml/dtd/sequence.dtd diff --git a/assets/schemas/xml/dtd/table.dtd b/assets/schemas/xml/dtd/table.dtd new file mode 100644 index 0000000000..a01ca763f6 --- /dev/null +++ b/assets/schemas/xml/dtd/table.dtd @@ -0,0 +1,36 @@ + + +%column; + +%constraint; + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/schemas/xml/dtd/tablespace.dtd b/assets/schemas/xml/dtd/tablespace.dtd similarity index 100% rename from schemas/xml/dtd/tablespace.dtd rename to assets/schemas/xml/dtd/tablespace.dtd diff --git a/schemas/xml/dtd/tag.dtd b/assets/schemas/xml/dtd/tag.dtd similarity index 82% rename from schemas/xml/dtd/tag.dtd rename to assets/schemas/xml/dtd/tag.dtd index 72cdefd1f3..0fe1591be4 100644 --- a/schemas/xml/dtd/tag.dtd +++ b/assets/schemas/xml/dtd/tag.dtd @@ -8,4 +8,4 @@ - + diff --git a/schemas/xml/dtd/textbox.dtd b/assets/schemas/xml/dtd/textbox.dtd similarity index 81% rename from schemas/xml/dtd/textbox.dtd rename to assets/schemas/xml/dtd/textbox.dtd index 5c3c86984a..5256fc600a 100644 --- a/schemas/xml/dtd/textbox.dtd +++ b/assets/schemas/xml/dtd/textbox.dtd @@ -1,9 +1,10 @@ - + @@ -11,3 +12,5 @@ + + diff --git a/assets/schemas/xml/dtd/transform.dtd b/assets/schemas/xml/dtd/transform.dtd new file mode 100644 index 0000000000..b4215616cb --- /dev/null +++ b/assets/schemas/xml/dtd/transform.dtd @@ -0,0 +1,7 @@ + + + + diff --git a/schemas/xml/dtd/trigger.dtd b/assets/schemas/xml/dtd/trigger.dtd similarity index 87% rename from schemas/xml/dtd/trigger.dtd rename to assets/schemas/xml/dtd/trigger.dtd index 22d745cd16..6c6f8672f9 100644 --- a/schemas/xml/dtd/trigger.dtd +++ b/assets/schemas/xml/dtd/trigger.dtd @@ -4,6 +4,7 @@ --> + @@ -18,3 +19,5 @@ + + diff --git a/assets/schemas/xml/dtd/usermapping.dtd b/assets/schemas/xml/dtd/usermapping.dtd new file mode 100644 index 0000000000..bf99399153 --- /dev/null +++ b/assets/schemas/xml/dtd/usermapping.dtd @@ -0,0 +1,9 @@ + + + + + + diff --git a/schemas/xml/dtd/usertype.dtd b/assets/schemas/xml/dtd/usertype.dtd similarity index 93% rename from schemas/xml/dtd/usertype.dtd rename to assets/schemas/xml/dtd/usertype.dtd index 6883df89ee..223d14841e 100644 --- a/schemas/xml/dtd/usertype.dtd +++ b/assets/schemas/xml/dtd/usertype.dtd @@ -1,8 +1,8 @@ - - + @@ -19,7 +19,7 @@ - + diff --git a/assets/schemas/xml/dtd/view.dtd b/assets/schemas/xml/dtd/view.dtd new file mode 100644 index 0000000000..b2329b4971 --- /dev/null +++ b/assets/schemas/xml/dtd/view.dtd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/schemas/xml/element.sch b/assets/schemas/xml/element.sch new file mode 100644 index 0000000000..6eae11f925 --- /dev/null +++ b/assets/schemas/xml/element.sch @@ -0,0 +1,16 @@ +# XML definition for operator classes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb [ $br +$tb {definition} +$tb $br diff --git a/assets/schemas/xml/entry.sch b/assets/schemas/xml/entry.sch new file mode 100644 index 0000000000..9b9d97e0f3 --- /dev/null +++ b/assets/schemas/xml/entry.sch @@ -0,0 +1,4 @@ +# XML definition for database model changelog entries +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$br $tb diff --git a/assets/schemas/xml/enumeration.sch b/assets/schemas/xml/enumeration.sch new file mode 100644 index 0000000000..86d0a55650 --- /dev/null +++ b/assets/schemas/xml/enumeration.sch @@ -0,0 +1,4 @@ +# XML definition for enumeration labels in user-defined types +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb [ $br \ No newline at end of file diff --git a/assets/schemas/xml/eventtrigger.sch b/assets/schemas/xml/eventtrigger.sch new file mode 100644 index 0000000000..045ffe8b8a --- /dev/null +++ b/assets/schemas/xml/eventtrigger.sch @@ -0,0 +1,28 @@ +# XML definition for event triggers +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +%if {function} %then {function} %end +%if {filter} %then {filter} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + + $br $br + diff --git a/assets/schemas/xml/excelement.sch b/assets/schemas/xml/excelement.sch new file mode 100644 index 0000000000..173a1fcc3d --- /dev/null +++ b/assets/schemas/xml/excelement.sch @@ -0,0 +1,31 @@ +# XML definition for exclude constraint elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb $tb $br + +%if {column} %then + $tb $tb $tb [ $br +%else + #%if {expression} %then + $tb $tb $tb $sp $sp $br + #%end +%end + +%if {opclass} %then + $tb $tb $tb {opclass} +%end + +#%if {operator} %then +$tb $tb $tb {operator} +#%end + +$tb $tb $br diff --git a/assets/schemas/xml/extension.sch b/assets/schemas/xml/extension.sch new file mode 100644 index 0000000000..e209bf034a --- /dev/null +++ b/assets/schemas/xml/extension.sch @@ -0,0 +1,36 @@ +# XML definition for extensions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +%if {schema} %then + {schema} +%end + +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + + $br $br diff --git a/assets/schemas/xml/foreigndatawrapper.sch b/assets/schemas/xml/foreigndatawrapper.sch new file mode 100644 index 0000000000..5b083765bf --- /dev/null +++ b/assets/schemas/xml/foreigndatawrapper.sch @@ -0,0 +1,37 @@ +# XML definition for indexes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {reduced-form} %then + $tb +%end + +[ $br +%else + %if {options} %then + [ options=] "&{options}" + %end + + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + %if {handler} %then {handler} %end + %if {validator} %then {validator} %end + + $br $br +%end diff --git a/assets/schemas/xml/foreignserver.sch b/assets/schemas/xml/foreignserver.sch new file mode 100644 index 0000000000..4336d624b3 --- /dev/null +++ b/assets/schemas/xml/foreignserver.sch @@ -0,0 +1,41 @@ +# XML definition for servers +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {reduced-form} %then $tb %end + +[ $br +%else + %if {type} %then + [ type=] "&{type}" + %end + + %if {version} %then + [ version=] "&{version}" + %end + + %if {options} %then + [ options=] "&{options}" + %end + + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + %if {fdw} %then {fdw} %end + + $br $br +%end diff --git a/assets/schemas/xml/foreigntable.sch b/assets/schemas/xml/foreigntable.sch new file mode 100644 index 0000000000..c68a584934 --- /dev/null +++ b/assets/schemas/xml/foreigntable.sch @@ -0,0 +1,42 @@ +# XML definition for tables +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +{schema} +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +{server} +%if {tag} %then {tag} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end +{position} + +%if {columns} %then {columns} %end +%if {constraints} %then {constraints} %end + +%if {col-indexes} %then {col-indexes} %end +%if {constr-indexes} %then {constr-indexes} %end + +%if {initial-data} %then + $tb $br + + $br $tb $br +%end + + + $br $br diff --git a/assets/schemas/xml/function.sch b/assets/schemas/xml/function.sch new file mode 100644 index 0000000000..37f81af008 --- /dev/null +++ b/assets/schemas/xml/function.sch @@ -0,0 +1,85 @@ +# XML definition for functions +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {reduced-form} %then $tb %end + + $br +%else + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + $br + $tb $tb window-func=%if {window-func} %then "true" %else "false" %end $br + + %if {leakproof} %then $tb $tb leakproof="true" $br %end + + $tb $tb returns-setof=%if {returns-setof} %then "true" %else "false" %end $br + $tb $tb behavior-type="{behavior-type}" $br + $tb $tb function-type="{function-type}" $br + $tb $tb security-type="{security-type}" $br + $tb $tb parallel-type="{parallel-type}" $br + $tb $tb execution-cost="{execution-cost}" $br + $tb $tb row-amount="{row-amount}" + > $br + + {schema} + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + %if {language} %then {language} %end + + $tb $br + + %if {return-table} %then + {return-table} + %else + {return-type} + %end + + $tb $br + + %if {transform-types} %then + $tb [ $br + %end + + %if {config-params} %then + {config-params} + %end + + %if {parameters} %then {parameters} %end + + + %if {library} %then + $tb [ $br + + %else + $tb $sp $sp $br + %end + + $br $br +%end diff --git a/assets/schemas/xml/genericsql.sch b/assets/schemas/xml/genericsql.sch new file mode 100644 index 0000000000..b281b9ad0c --- /dev/null +++ b/assets/schemas/xml/genericsql.sch @@ -0,0 +1,20 @@ +# XML definition for generic sql objects +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +$tb $sp $sp $br + +%if {objects} %then {objects} %end + + $br $br diff --git a/assets/schemas/xml/idxelement.sch b/assets/schemas/xml/idxelement.sch new file mode 100644 index 0000000000..62706517a9 --- /dev/null +++ b/assets/schemas/xml/idxelement.sch @@ -0,0 +1,31 @@ +# XML definition for indexes elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb $tb $br + +%if {column} %then + $tb $tb $tb [ $br +%else + #%if {expression} %then + $tb $tb $tb $sp $sp $br + #%end +%end + +%if {collation} %then + $tb $tb {collation} +%end + +%if {opclass} %then + $tb $tb $tb {opclass} +%end + +$tb $tb $br diff --git a/assets/schemas/xml/index.sch b/assets/schemas/xml/index.sch new file mode 100644 index 0000000000..adeb97690f --- /dev/null +++ b/assets/schemas/xml/index.sch @@ -0,0 +1,46 @@ +# XML definition for indexes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[ $br + +%if {tablespace} %then {tablespace} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +{elements} + +%if {predicate} %then + $tb $sp $sp $br +%end + +%if {include-cols} %then + $tb [] $br +%end + + $br $br diff --git a/assets/schemas/xml/info.sch b/assets/schemas/xml/info.sch new file mode 100644 index 0000000000..b4eeb4e028 --- /dev/null +++ b/assets/schemas/xml/info.sch @@ -0,0 +1,108 @@ +# XML definition for a single object's metadata +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%set {space} $br $tb $tb + +$tb [ $br + %if {position} %then {position} %end + %if {appended-sql} %then $tb {appended-sql} %end + %if {prepended-sql} %then $tb {prepended-sql} %end + $tb +%else + [/>] +%end + +$br diff --git a/assets/schemas/xml/label.sch b/assets/schemas/xml/label.sch new file mode 100644 index 0000000000..a1dca9825a --- /dev/null +++ b/assets/schemas/xml/label.sch @@ -0,0 +1,6 @@ +# XML definition for relationship label positioning +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb $br \ No newline at end of file diff --git a/assets/schemas/xml/language.sch b/assets/schemas/xml/language.sch new file mode 100644 index 0000000000..aa3a2781d3 --- /dev/null +++ b/assets/schemas/xml/language.sch @@ -0,0 +1,34 @@ +# XML definition for schemas +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {reduced-form} %then $tb %end + +[] $br +%else + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + [ trusted=] %if {trusted} %then "true" %else "false" %end + + [>]$br + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + %if {handler} %then {handler} %end + %if {validator} %then {validator} %end + %if {inline} %then {inline} %end + + $br $br +%end diff --git a/assets/schemas/xml/metadata.sch b/assets/schemas/xml/metadata.sch new file mode 100644 index 0000000000..b0cba3a577 --- /dev/null +++ b/assets/schemas/xml/metadata.sch @@ -0,0 +1,11 @@ +# XML definition for graphical object metada file +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + $br +[] $br + $br +%if {info} %then {info} %end + diff --git a/assets/schemas/xml/object.sch b/assets/schemas/xml/object.sch new file mode 100644 index 0000000000..fd2d727060 --- /dev/null +++ b/assets/schemas/xml/object.sch @@ -0,0 +1,15 @@ +# XML definition for custom index for a single column or constraint +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {index} %then $tb %end +$tb [ $br diff --git a/assets/schemas/xml/opclass.sch b/assets/schemas/xml/opclass.sch new file mode 100644 index 0000000000..c566376ea3 --- /dev/null +++ b/assets/schemas/xml/opclass.sch @@ -0,0 +1,43 @@ +# XML definition for operator classes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br +%else + + [ index-type=] "{index-type}" + [ default=] %if {default} %then "true" %else "false" %end + + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + {schema} + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + %if {family} %then + $tb [] $br + %end + + {type} + {elements} + + $br $br +%end diff --git a/assets/schemas/xml/operator.sch b/assets/schemas/xml/operator.sch new file mode 100644 index 0000000000..f0d7a8ce3d --- /dev/null +++ b/assets/schemas/xml/operator.sch @@ -0,0 +1,45 @@ +# XML definition for schemas +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {reduced-form} %then $tb %end + +[ $br +%else + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + {schema} + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + %if {left-type} %then {left-type} %end + %if {right-type} %then {right-type} %end + + + %if {commutator-op} %then {commutator-op} %end + %if {negator-op} %then {negator-op} %end + %if {operfunc} %then {operfunc} %end + %if {join} %then {join} %end + %if {restriction} %then {restriction} %end + + $br $br +%end diff --git a/assets/schemas/xml/opfamily.sch b/assets/schemas/xml/opfamily.sch new file mode 100644 index 0000000000..2b43768c61 --- /dev/null +++ b/assets/schemas/xml/opfamily.sch @@ -0,0 +1,30 @@ +# XML definition for operator families +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +%if {reduced-form} %then $tb %end + +[ $br +%else + [name=] "&{name}" [ index-type=] "{index-type}" + + %if {protected} %then + [ protected=] "true" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + > $br + + {schema} + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + $br $br +%end diff --git a/assets/schemas/xml/parameter.sch b/assets/schemas/xml/parameter.sch new file mode 100644 index 0000000000..10ba6adb7a --- /dev/null +++ b/assets/schemas/xml/parameter.sch @@ -0,0 +1,13 @@ +# XML definition for function parameters +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb [$br + +$tb {type} + +$tb $br diff --git a/assets/schemas/xml/partitionkey.sch b/assets/schemas/xml/partitionkey.sch new file mode 100644 index 0000000000..0a61bf6eda --- /dev/null +++ b/assets/schemas/xml/partitionkey.sch @@ -0,0 +1,20 @@ +# XML definition for indexes elements +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb $tb $br + +%if {column} %then + $tb $tb $tb [ $br +%else + $tb $tb $tb $sp $sp $br +%end + +%if {collation} %then + $tb $tb {collation} +%end + +%if {opclass} %then + $tb $tb $tb {opclass} +%end + +$tb $tb $br diff --git a/assets/schemas/xml/permission.sch b/assets/schemas/xml/permission.sch new file mode 100644 index 0000000000..23032d6028 --- /dev/null +++ b/assets/schemas/xml/permission.sch @@ -0,0 +1,48 @@ +# XML definition for grants +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + $br + + +$tb [] $br + +%if {roles} %then + $tb [] $br +%end + +$tb [] $br + + $br diff --git a/assets/schemas/xml/policy.sch b/assets/schemas/xml/policy.sch new file mode 100644 index 0000000000..1747209068 --- /dev/null +++ b/assets/schemas/xml/policy.sch @@ -0,0 +1,37 @@ +# XML definition for policies +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +[ $br + +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +%if {roles} %then + $tb [] +%end + +%if {using-exp} %then + $br $tb [] $sp $sp +%end + +%if {check-exp} %then + $br $tb [] $sp $sp +%end + +$br + + diff --git a/assets/schemas/xml/position.sch b/assets/schemas/xml/position.sch new file mode 100644 index 0000000000..de227501b6 --- /dev/null +++ b/assets/schemas/xml/position.sch @@ -0,0 +1,5 @@ +# XML definition for object positioning +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb [ $br diff --git a/assets/schemas/xml/prependedsql.sch b/assets/schemas/xml/prependedsql.sch new file mode 100644 index 0000000000..d241a46050 --- /dev/null +++ b/assets/schemas/xml/prependedsql.sch @@ -0,0 +1,9 @@ +# XML definition for prepended SQL commands +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +#Creates element envolving the prepended-sql +#The tag is converted to in order +#to not cause syntax errors on the schema parser + +$tb $sp $sp $br diff --git a/assets/schemas/xml/procedure.sch b/assets/schemas/xml/procedure.sch new file mode 100644 index 0000000000..1798ad052c --- /dev/null +++ b/assets/schemas/xml/procedure.sch @@ -0,0 +1,41 @@ +# XML definition for procedures +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + + $br + +{schema} + +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end +%if {language} %then {language} %end + +%if {transform-types} %then + $tb [ $br +%end + +%if {config-params} %then + {config-params} +%end + +%if {parameters} %then {parameters} %end + +%if {library} %then + $tb [ $br +%else + $tb $sp $sp $br +%end + + $br $br diff --git a/assets/schemas/xml/reference.sch b/assets/schemas/xml/reference.sch new file mode 100644 index 0000000000..1524b5e7cd --- /dev/null +++ b/assets/schemas/xml/reference.sch @@ -0,0 +1,30 @@ +# XML definition for view references +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +$tb $br + + $tb $tb $sp $sp $br + + %if {columns} %then {columns} %end + %if {ref-tables} %then {ref-tables} %end + + $tb $br +%else + /> $br +%end diff --git a/assets/schemas/xml/reftable.sch b/assets/schemas/xml/reftable.sch new file mode 100644 index 0000000000..a4ea2e787c --- /dev/null +++ b/assets/schemas/xml/reftable.sch @@ -0,0 +1,5 @@ +# XML definition for view references +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb $tb [] $br diff --git a/assets/schemas/xml/relationship.sch b/assets/schemas/xml/relationship.sch new file mode 100644 index 0000000000..8de5ca85d9 --- /dev/null +++ b/assets/schemas/xml/relationship.sch @@ -0,0 +1,120 @@ +# XML definition for relationships +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br $br +%else + > $br + + %if {points} %then $tb $br $tb {points} $tb $br %end + %if {labels-pos} %then {labels-pos} %end + + %if %not {relgen} %and %not {reldep} %and %not {relpart} %then + %if {columns} %then {columns} %end + %if {constraints} %then {constraints} %end + %end + + %if {original-pk} %then + {original-pk} + %end + + %if {special-pk-cols} %then + $tb [ $br + %end + + %if {partition-bound-expr} %then + $tb $sp $sp $br + %end + + $br $br +%end diff --git a/assets/schemas/xml/role.sch b/assets/schemas/xml/role.sch new file mode 100644 index 0000000000..5621eb53d0 --- /dev/null +++ b/assets/schemas/xml/role.sch @@ -0,0 +1,39 @@ +# XML definition for roles +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {reduced-form} %then $tb %end +[ $br +%else + %if {superuser} %then $br [ superuser="true"] %end + %if {createdb} %then $br [ createdb="true"] %end + %if {replication} %then $br [ replication="true"] %end + %if {createrole} %then $br [ createrole="true"] %end + %if {inherit} %then $br [ inherit="true"] %end + %if {login} %then $br [ login="true"] %end + %if {bypassrls} %then $br [ bypassrls="true"] %end + %if {connlimit} %then $br [ connlimit=]"{connlimit}" %end + %if {validity} %then $br [ validity=]"{validity}" %end + %if {password} %then $br [ password=]"&{password}" %end + + %if {protected} %then + $br [ protected="true"] + %end + + %if {sql-disabled} %then + $br [ sql-disabled="true"] + %end + + > $br + + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + %if {member-roles} %then $tb [] $br %end + %if {admin-roles} %then $tb [] $br %end + + $br $br +%end diff --git a/assets/schemas/xml/rule.sch b/assets/schemas/xml/rule.sch new file mode 100644 index 0000000000..8f99dc3b78 --- /dev/null +++ b/assets/schemas/xml/rule.sch @@ -0,0 +1,37 @@ +# XML definition for indexes +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +%if {comment} %then $tb {comment} %end + +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + +%if {condition} %then + $tb $tb $sp $sp $br +%end + +%if {commands} %then + $tb $tb $sp $sp $br +%end + + $br $br diff --git a/assets/schemas/xml/schema.sch b/assets/schemas/xml/schema.sch new file mode 100644 index 0000000000..9a286e93b7 --- /dev/null +++ b/assets/schemas/xml/schema.sch @@ -0,0 +1,50 @@ +# XML definition for schemas +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +%if {reduced-form} %then $tb %end +[ $br +%else + %if {layers} %then + [ layers=] "{layers}" + %end + + %if {alias} %then + $sp alias="&{alias}" + %end + + %if {protected} %then + [ protected=] "true" + %end + + %if {rect-visible} %then + [ rect-visible=] "true" + %end + + %if {fill-color} %then + [ fill-color=] "{fill-color}" + %end + + %if {name-color} %then + [ name-color=] "{name-color}" + %end + + %if {sql-disabled} %then + [ sql-disabled=] "true" + %end + + %if {faded-out} %then + [ faded-out=] "true" + %end + + > $br + + %if {owner} %then {owner} %end + %if {comment} %then {comment} %end + %if {appended-sql} %then {appended-sql} %end + %if {prepended-sql} %then {prepended-sql} %end + + $br $br +%end diff --git a/assets/schemas/xml/sequence.sch b/assets/schemas/xml/sequence.sch new file mode 100644 index 0000000000..6269f3445e --- /dev/null +++ b/assets/schemas/xml/sequence.sch @@ -0,0 +1,47 @@ +# XML definition for sequences +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. +[ $br + +{schema} +%if {owner} %then {owner} %end +%if {comment} %then {comment} %end +%if {appended-sql} %then {appended-sql} %end +%if {prepended-sql} %then {prepended-sql} %end + $br $br diff --git a/assets/schemas/xml/style.sch b/assets/schemas/xml/style.sch new file mode 100644 index 0000000000..8529e0bcf1 --- /dev/null +++ b/assets/schemas/xml/style.sch @@ -0,0 +1,7 @@ +# XML definition for object tag styles +# CAUTION: Do not modify this file unless you know what you are doing. +# Code generation can be broken if incorrect changes are made. + +$tb [