├── .gitignore
├── LICENSE
├── README.md
├── SqlBrowserFX.exe
├── build.sh
├── create-jre.sh
├── images
└── sqlbrowserfx.png
├── increaseVersion.groovy
├── install.sh
├── l4j-config.xml
├── logo.txt
├── pom.xml
├── prepare-version.sh
├── sqlbrowser-for-build.db
├── sqlbrowser-fx.ico
├── sqlbrowserfx.properties
├── src
├── main
│ ├── java
│ │ ├── gr
│ │ │ └── sqlbrowserfx
│ │ │ │ ├── GUIStarter.java
│ │ │ │ ├── LoggerConf.java
│ │ │ │ ├── SqlBrowserFXApp.java
│ │ │ │ ├── SqlBrowserFXAppManager.java
│ │ │ │ ├── SqlBrowserFXAppWithoutDocking.java
│ │ │ │ ├── conn
│ │ │ │ ├── DbCash.java
│ │ │ │ ├── MysqlConnector.java
│ │ │ │ ├── PostgreSqlConnector.java
│ │ │ │ ├── ResultSetAction.java
│ │ │ │ ├── SqlConnector.java
│ │ │ │ ├── SqlServerConnector.java
│ │ │ │ ├── SqlTable.java
│ │ │ │ ├── SqliteConnector.java
│ │ │ │ ├── StatementAction.java
│ │ │ │ └── UpdateQuery.java
│ │ │ │ ├── dock
│ │ │ │ └── nodes
│ │ │ │ │ ├── DDBTreePane.java
│ │ │ │ │ ├── DDBTreeView.java
│ │ │ │ │ ├── DDbDiagramPane.java
│ │ │ │ │ ├── DLogConsolePane.java
│ │ │ │ │ ├── DSqlConsolePane.java
│ │ │ │ │ ├── DSqlConsolePaneNH.java
│ │ │ │ │ └── DSqlPane.java
│ │ │ │ ├── factories
│ │ │ │ └── DialogFactory.java
│ │ │ │ ├── listeners
│ │ │ │ ├── SimpleEvent.java
│ │ │ │ ├── SimpleObservable.java
│ │ │ │ ├── SimpleObserver.java
│ │ │ │ ├── TableColumnFilteringEvent.java
│ │ │ │ └── TableSearchFilteringEvent.java
│ │ │ │ ├── nodes
│ │ │ │ ├── ColumnCreationBox.java
│ │ │ │ ├── ContextMenuOwner.java
│ │ │ │ ├── DBTreeView.java
│ │ │ │ ├── DbConfigBox.java
│ │ │ │ ├── DbDiagramPane.java
│ │ │ │ ├── FileSearchPopOver.java
│ │ │ │ ├── FilesTreeView.java
│ │ │ │ ├── HelpShortcutsTabPane.java
│ │ │ │ ├── HelpTabPane.java
│ │ │ │ ├── InputMapOwner.java
│ │ │ │ ├── LogConsolePane.java
│ │ │ │ ├── MySqlConfigBox.java
│ │ │ │ ├── NoSelectionModel.java
│ │ │ │ ├── PostgreSqlConfigBox.java
│ │ │ │ ├── SearchAndReplacePopOver.java
│ │ │ │ ├── SimpleTerminalPane.java
│ │ │ │ ├── SqlConnectorType.java
│ │ │ │ ├── SqlConsolePane.java
│ │ │ │ ├── SqlServerConfigBox.java
│ │ │ │ ├── SqlTableNode.java
│ │ │ │ ├── TableCreationPane.java
│ │ │ │ ├── ToolbarOwner.java
│ │ │ │ ├── TreeViewFile.java
│ │ │ │ ├── codeareas
│ │ │ │ │ ├── AutoCompleteCodeArea.java
│ │ │ │ │ ├── CodeAreaSyntaxProvider.java
│ │ │ │ │ ├── FileCodeArea.java
│ │ │ │ │ ├── FormatterMode.java
│ │ │ │ │ ├── HighLighter.java
│ │ │ │ │ ├── Keyword.java
│ │ │ │ │ ├── KeywordType.java
│ │ │ │ │ ├── SearchableCodeArea.java
│ │ │ │ │ ├── SimpleFileCodeArea.java
│ │ │ │ │ ├── SimpleFileCodeAreaSyntaxProvider.java
│ │ │ │ │ ├── SuggestionListCell.java
│ │ │ │ │ ├── TextAnalyzer.java
│ │ │ │ │ ├── java
│ │ │ │ │ │ ├── FileJavaCodeArea.java
│ │ │ │ │ │ ├── JavaCodeArea.java
│ │ │ │ │ │ └── JavaCodeAreaSyntaxProvider.java
│ │ │ │ │ ├── log
│ │ │ │ │ │ ├── CodeAreaTailerListener.java
│ │ │ │ │ │ ├── LogCodeArea.java
│ │ │ │ │ │ └── LogCodeAreaSyntaxProvider.java
│ │ │ │ │ └── sql
│ │ │ │ │ │ ├── CSqlCodeArea.java
│ │ │ │ │ │ ├── FileSqlCodeArea.java
│ │ │ │ │ │ ├── HistorySqlCodeArea.java
│ │ │ │ │ │ ├── PHistorySqlCodeArea.java
│ │ │ │ │ │ ├── SimpleLineNumberFactory.java
│ │ │ │ │ │ ├── SqlCodeArea.java
│ │ │ │ │ │ └── SqlCodeAreaSyntaxProvider.java
│ │ │ │ ├── queriesmenu
│ │ │ │ │ ├── QueriesMenu.java
│ │ │ │ │ └── QueryDTO.java
│ │ │ │ ├── sqlpane
│ │ │ │ │ ├── CustomPopOver.java
│ │ │ │ │ ├── DraggingTabPaneSupport.java
│ │ │ │ │ ├── SimpleSqlPane.java
│ │ │ │ │ ├── SqlPane.java
│ │ │ │ │ ├── SqlTableRowEditBox.java
│ │ │ │ │ └── SqlTableTab.java
│ │ │ │ └── tableviews
│ │ │ │ │ ├── EditableCell.java
│ │ │ │ │ ├── HistorySqlTableView.java
│ │ │ │ │ ├── JSONTableView.java
│ │ │ │ │ ├── MapTableViewRow.java
│ │ │ │ │ ├── SqlTableView.java
│ │ │ │ │ ├── SqlTableViewCell.java
│ │ │ │ │ ├── SqlTableViewEditableCell.java
│ │ │ │ │ ├── TableViewCellEditArea.java
│ │ │ │ │ ├── TableViewCellEditField.java
│ │ │ │ │ └── filter
│ │ │ │ │ ├── ColumnFilter.java
│ │ │ │ │ ├── DupeCounter.java
│ │ │ │ │ ├── FilterPanel.java
│ │ │ │ │ ├── FilterValue.java
│ │ │ │ │ ├── SqlTableFilter.java
│ │ │ │ │ ├── TableFilter.java
│ │ │ │ │ └── TableViewUtils.java
│ │ │ │ ├── rest
│ │ │ │ ├── RESTfulService.java
│ │ │ │ └── RESTfulServiceConfig.java
│ │ │ │ └── utils
│ │ │ │ ├── FilesUtils.java
│ │ │ │ ├── HttpClient.java
│ │ │ │ ├── JavaFXUtils.java
│ │ │ │ ├── MemoryGuard.java
│ │ │ │ ├── PropertiesLoader.java
│ │ │ │ ├── Property.java
│ │ │ │ ├── SqlFormatter.java
│ │ │ │ └── mapper
│ │ │ │ ├── Column.java
│ │ │ │ ├── DTO.java
│ │ │ │ └── DTOMapper.java
│ │ ├── org
│ │ │ └── dockfx
│ │ │ │ ├── DockEvent.java
│ │ │ │ ├── DockNode.java
│ │ │ │ ├── DockPane.java
│ │ │ │ ├── DockPos.java
│ │ │ │ ├── DockTabPane.java
│ │ │ │ ├── DockTitleBar.java
│ │ │ │ ├── DockWeights.java
│ │ │ │ └── Dockable.java
│ │ └── res-to-styles.sh
│ └── resources
│ │ ├── log4j2.properties
│ │ └── styles
│ │ ├── classic.css
│ │ ├── fix-missing-icons.sh
│ │ ├── flat-dark.css
│ │ ├── flat-dark
│ │ └── icons
│ │ │ ├── add.png
│ │ │ ├── blue.png
│ │ │ ├── chart-pie.png
│ │ │ ├── chart.png
│ │ │ ├── check.png
│ │ │ ├── clear.png
│ │ │ ├── close-win-w.png
│ │ │ ├── close-win.png
│ │ │ ├── close.png
│ │ │ ├── code-file.png
│ │ │ ├── collapse.png
│ │ │ ├── columns.png
│ │ │ ├── compare.png
│ │ │ ├── console.png
│ │ │ ├── copy.png
│ │ │ ├── csv-import.png
│ │ │ ├── csv.png
│ │ │ ├── cut.png
│ │ │ ├── database.png
│ │ │ ├── details.png
│ │ │ ├── diagram.png
│ │ │ ├── edit.png
│ │ │ ├── filter.png
│ │ │ ├── folder.png
│ │ │ ├── foreign-key.png
│ │ │ ├── format.png
│ │ │ ├── function.png
│ │ │ ├── green.png
│ │ │ ├── help.png
│ │ │ ├── icons8-pulse-20.png
│ │ │ ├── index.png
│ │ │ ├── javalin-logo.png
│ │ │ ├── lowercase.png
│ │ │ ├── m-database.png
│ │ │ ├── magnify.png
│ │ │ ├── mariadb.png
│ │ │ ├── maximize-win-w.png
│ │ │ ├── maximize-win.png
│ │ │ ├── maximize.png
│ │ │ ├── menu-edit.png
│ │ │ ├── menu.png
│ │ │ ├── minus.png
│ │ │ ├── monitor.png
│ │ │ ├── mysql.png
│ │ │ ├── next.png
│ │ │ ├── no.png
│ │ │ ├── old
│ │ │ ├── add.png
│ │ │ ├── check.png
│ │ │ ├── clear.png
│ │ │ ├── code-file.png
│ │ │ ├── collapse.png
│ │ │ ├── columns.png
│ │ │ ├── compare.png
│ │ │ ├── console.png
│ │ │ ├── copy.png
│ │ │ ├── csv-import.png
│ │ │ ├── csv.png
│ │ │ ├── cut.png
│ │ │ ├── database.png
│ │ │ ├── details.png
│ │ │ ├── edit.png
│ │ │ ├── filter.png
│ │ │ ├── foreign-key.png
│ │ │ ├── format.png
│ │ │ ├── function.png
│ │ │ ├── help.png
│ │ │ ├── icons8-lightning-bolt-20.png
│ │ │ ├── index.png
│ │ │ ├── lowercase.png
│ │ │ ├── magnify.png
│ │ │ ├── minus.png
│ │ │ ├── monitor.png
│ │ │ ├── next.png
│ │ │ ├── no.png
│ │ │ ├── open-view.png
│ │ │ ├── openTab.png
│ │ │ ├── paste.png
│ │ │ ├── play.png
│ │ │ ├── primary-key.png
│ │ │ ├── procedure.png
│ │ │ ├── refresh.png
│ │ │ ├── replace.png
│ │ │ ├── save.png
│ │ │ ├── script.png
│ │ │ ├── settings.png
│ │ │ ├── stop.png
│ │ │ ├── structure.png
│ │ │ ├── suggestion.png
│ │ │ ├── table-e.png
│ │ │ ├── table-settings.png
│ │ │ ├── table-y.png
│ │ │ ├── table.png
│ │ │ ├── thunder.png
│ │ │ ├── transaction.png
│ │ │ ├── trigger.png
│ │ │ ├── uppercase.png
│ │ │ ├── view.png
│ │ │ ├── web.png
│ │ │ ├── yes.png
│ │ │ └── zoom.png
│ │ │ ├── open-view.png
│ │ │ ├── openTab.png
│ │ │ ├── paste.png
│ │ │ ├── pin.png
│ │ │ ├── play.png
│ │ │ ├── postgre.png
│ │ │ ├── primary-key.png
│ │ │ ├── procedure.png
│ │ │ ├── red.png
│ │ │ ├── refresh.png
│ │ │ ├── replace.png
│ │ │ ├── restore-win-w.png
│ │ │ ├── restore-win.png
│ │ │ ├── restore.png
│ │ │ ├── save.png
│ │ │ ├── script.png
│ │ │ ├── settings.png
│ │ │ ├── spark.png
│ │ │ ├── sqlbrowser-fx.png
│ │ │ ├── sqlite.png
│ │ │ ├── sqlserver.png
│ │ │ ├── stop.png
│ │ │ ├── structure.png
│ │ │ ├── suggestion.png
│ │ │ ├── table-e.png
│ │ │ ├── table-settings.png
│ │ │ ├── table-y.png
│ │ │ ├── table.png
│ │ │ ├── thunder.png
│ │ │ ├── transaction.png
│ │ │ ├── trigger.png
│ │ │ ├── uppercase.png
│ │ │ ├── var.png
│ │ │ ├── view.png
│ │ │ ├── web.png
│ │ │ ├── yes.png
│ │ │ └── zoom.png
│ │ ├── flat-dark2.css
│ │ ├── flat-gray.css
│ │ └── flat-purple.css
└── test
│ └── java
│ └── sqlbrowserfx
│ ├── FilesTreeViewTestGui.java
│ ├── GuiTestStarter.java
│ ├── JavaCodeAreaTestGui.java
│ ├── JsonTableViewTestGui.java
│ ├── SqlPaneTestGui.java
│ └── TableCreationPaneTestGui.java
└── starters
├── SqlBrowserFX.exe
└── sqlbrowserfx.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .settings
4 | logs
5 | out
6 | target
7 | lib
8 | *.log
9 | dist
10 | .gradle/
11 | .idea/
12 | sqlbrowserfx.iml
13 | sqlbrowser.db
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019-2023 Paris Kolovos
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SqlBrowserFX
2 |
3 | SqlBrowserFX is a feature rich cross platform sql client for SQLite , MySQL, MariaDB and PostgreSQL (partially supported).
4 |
5 | 
6 |
7 | ### Features
8 |
9 | * Manage data (insert, update, delete) via gui.
10 | * Execute raw sql queries.
11 | * Editor for sql with syntax highlighting, autocomplete, refactoring features.
12 | * Support for sql, java files editing via drag and drop.
13 | * Adjustable responsive ui supporting multiple code areas and tables opened at the same time.
14 | * Graphical representation of database as tree.
15 | * Graphical representation of database as diagram.
16 | * Exposure of database to the web as RESTful service with one click.
17 | * Import, export csv files.
18 | * Queries History.
19 | * Savable queries.
20 | * Support for SQLite.
21 | * Support for MySQL, MariaDB.
22 | * Partial Support for PostgreSQL.
23 | * Cross Platform.
24 | * Css themable (Dark, Light etc).
25 | * Generation of simple database tables diagram.
26 |
27 | ### Prerequisites
28 |
29 | * Java 21 +
30 | * Installation of desired database.
31 |
32 | ### Installing
33 |
34 | Copy sqlbrowser-for-build.db to sqlbrowser.db.
35 | Import the project to your favorite ide as maven project and run GUIStarter class.
36 | You can also run install.sh script , if you are using linux in order to install sqlbrowserfx as cli command
37 | 'sqlfx'.
38 |
39 | ### Compatibility with older versions of java
40 | * Tag 2.5.0 -> Java 17
41 | * Tag 1.5.0 -> Java 8
42 |
43 |
44 | ### Build standalone app
45 |
46 | Run build.sh script, this will generate all files needed in 'dist' folder.
47 | Run SqlBrowserFX.exe for Windows, or run sqlbrowserfx.sh for Linux.
48 |
49 |
50 | ## Awesome projects used
51 |
52 | * [DockFX](https://github.com/RobertBColton/DockFX) - The docking framework used (a moded version actually).
53 | * [RichTextFΧ](https://github.com/FXMisc/RichTextFX) - Library which provides editor with syntax highlighting feature.
54 | * [ControlsFX](https://github.com/controlsfx/controlsfx) - Library which provides many useful custom gui components.
55 | * [Spark Java](https://github.com/perwendel/spark) - The web framework used. (Until version 1.5.0)
56 | * [Javalin](https://github.com/tipsy/javalin) - The NEW web framework used.
57 | * [Icons8](https://icons8.com/) - The icons used.
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/SqlBrowserFX.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pariskol/sqlbrowserfx/433976953de44268e2e9bca634e12547cd14a886/SqlBrowserFX.exe
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | get_version_from_pom() {
4 | grep -ioh -m 1 ".*" pom.xml | sed "s///g" | sed "s/<\/version>//g"
5 | }
6 |
7 | cd "$(dirname "$0")"
8 |
9 | pom=pom.xml
10 | [ ! -z "$1" ] && pom=$1
11 |
12 | rm -rf dist
13 | mkdir -p dist/sqlbrowserfx/lib
14 |
15 | mvn clean package -f $pom
16 | if [ $? -ne 0 ]
17 | then
18 | echo "Error : could not package project!"
19 | exit 1
20 | fi
21 | mvn dependency:copy-dependencies
22 | if [ $? -ne 0 ]
23 | then
24 | echo "Error : could not download dependencies!"
25 | exit 2
26 | fi
27 |
28 |
29 | cp target/sqlbrowserfx*.jar dist/sqlbrowserfx/sqlbrowserfx.jar
30 | cp target/dependency/* dist/sqlbrowserfx/lib
31 | cp log4j.properties dist/sqlbrowserfx/
32 | cp sqlbrowser-for-build.db dist/sqlbrowserfx/sqlbrowser.db
33 | cp starters/* dist/sqlbrowserfx/
34 | cp sqlbrowserfx.properties dist/sqlbrowserfx/
35 |
36 | version=$(get_version_from_pom)
37 | chmod +x dist/sqlbrowserfx/*.sh
38 | cd dist
39 |
40 | tar -czvf sqlbrowserfx-$version.tar.gz *
41 |
--------------------------------------------------------------------------------
/create-jre.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | modules="java.base,java.datatransfer,java.desktop,jdk.unsupported,java.logging,java.sql"
4 | jlink --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules $modules --output jre
5 |
--------------------------------------------------------------------------------
/images/sqlbrowserfx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pariskol/sqlbrowserfx/433976953de44268e2e9bca634e12547cd14a886/images/sqlbrowserfx.png
--------------------------------------------------------------------------------
/increaseVersion.groovy:
--------------------------------------------------------------------------------
1 |
2 | version=args[0]
3 |
4 | split=version.split("\\.")
5 | newMinor=split[2].toInteger() + 1
6 | split[2]=newMinor
7 |
8 | println(split.join("."))
9 |
10 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cat logo.txt
4 | ./build.sh
5 | mkdir -p ~/sqlbrowserfx
6 | cp -r dist/sqlbrowserfx/* ~/sqlbrowserfx/
7 | cp starters/sqlbrowserfx.sh ~/sqlbrowserfx/
8 | echo
9 | echo "Fixing starter script.."
10 | #sed -i "s|#JAVA_HOME|export JAVA_HOME=$JAVA_HOME/bin|g" ~/sqlbrowserfx/sqlbrowserfx.sh
11 | chmod +x ~/sqlbrowserfx/sqlbrowserfx.sh
12 | echo "Checking for .bash_aliases..."
13 | [ ! -f .bash_aliases ] && touch ~/.bash_aliases
14 | echo "Adding alias for SqlBrowserFX..."
15 | [ $(grep -c "sqlfx" ~/.bash_aliases) -eq 0 ] && echo "alias sqlfx=~/sqlbrowserfx/sqlbrowserfx.sh" >> ~/.bash_aliases
16 | source ~/.bashrc
17 | echo
18 | echo "Installation finished"
19 | echo
20 | echo "Start sqlbrowserdfx from cli by running sqlfx"
--------------------------------------------------------------------------------
/l4j-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | gui
5 | ./sqlbrowserfx.jar
6 | ./SqlBrowserFX.exe
7 |
8 |
9 | .
10 | high
11 |
12 |
13 | false
14 | false
15 |
16 | ./sqlbrowser-fx.ico
17 |
18 | gr.sqlbrowserfx.GUIStarter
19 | ./lib/*
20 |
21 |
22 | jre
23 | false
24 | true
25 | 21
26 |
27 | -Xmx512m -Xms128m -XX:+UseG1GC -XX:MaxGCPauseMillis=100
28 |
29 |
30 |
--------------------------------------------------------------------------------
/logo.txt:
--------------------------------------------------------------------------------
1 | _____ _ ____ ________ __
2 | / ____| | | _ \ | ____\ \ / /
3 | | (___ __ _| | |_) |_ __ _____ _____ ___ _ __| |__ \ V /
4 | \___ \ / _` | | _ <| '__/ _ \ \ /\ / / __|/ _ \ '__| __| > <
5 | ____) | (_| | | |_) | | | (_) \ V V /\__ \ __/ | | | / . \
6 | |_____/ \__, |_|____/|_| \___/ \_/\_/ |___/\___|_| |_| /_/ \_\
7 | | |
8 | |_|
9 |
--------------------------------------------------------------------------------
/prepare-version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd "$(dirname "$0")"
4 |
5 | version=$1
6 |
7 | if [ -z "$version" ]
8 | then
9 | echo "Provide target version!"
10 | exit 1
11 | fi
12 | # check groovy
13 | groovy -version || exit 2
14 |
15 | sed -i "0,/.*<\/version>/s//$version<\/version>/" pom.xml
16 | git add pom.xml
17 | git commit -m "prepare realase $version"
18 | git tag $version
19 | git push --tags
20 |
21 | newVersion=$(groovy increaseVersion.groovy $version)
22 | sed -i "0,/.*<\/version>/s//$newVersion-SNAPSHOT<\/version>/" pom.xml
23 | git add pom.xml
24 | git commit -m "restore pom after release"
25 | git push origin development
26 | git checkout master
27 | git merge $version
28 | git push origin master
29 | git checkout development
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/sqlbrowser-for-build.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pariskol/sqlbrowserfx/433976953de44268e2e9bca634e12547cd14a886/sqlbrowser-for-build.db
--------------------------------------------------------------------------------
/sqlbrowser-fx.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pariskol/sqlbrowserfx/433976953de44268e2e9bca634e12547cd14a886/sqlbrowser-fx.ico
--------------------------------------------------------------------------------
/sqlbrowserfx.properties:
--------------------------------------------------------------------------------
1 | # classic, flat-dark, flat-dark2, flat-gray, flat-purple
2 | sqlbrowserfx.css.theme=flat-dark
3 | #sqlbrowserfx.jmetro.theme=dark
4 | # normal, simple, advanced
5 | sqlbrowserfx.mode=advanced
6 | sqlbrowserfx.default.editmode.cell=false
7 | sqlbrowserfx.root.path=/home/paris/eclipse-workspace
8 | sqlconnector.enable.autocommit=true
9 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/GUIStarter.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx;
2 |
3 | import gr.sqlbrowserfx.utils.PropertiesLoader;
4 |
5 | public class GUIStarter {
6 |
7 | public static void main(String[] args) {
8 | if (PropertiesLoader.getProperty("sqlbrowserfx.mode", String.class, "advanced").equals("advanced"))
9 | SqlBrowserFXApp.main(args);
10 | else
11 | SqlBrowserFXAppWithoutDocking.main(args);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/LoggerConf.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx;
2 |
3 | public class LoggerConf {
4 |
5 | public static final String LOGGER_NAME = "sqlbrowserfx";
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/SqlBrowserFXAppManager.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Objects;
6 | import java.util.stream.Collectors;
7 |
8 | import gr.sqlbrowserfx.conn.SqlConnector;
9 | import gr.sqlbrowserfx.conn.SqliteConnector;
10 | import gr.sqlbrowserfx.dock.nodes.DDBTreeView;
11 | import gr.sqlbrowserfx.dock.nodes.DSqlConsolePane;
12 | import gr.sqlbrowserfx.dock.nodes.DSqlPane;
13 | import gr.sqlbrowserfx.nodes.sqlpane.SqlPane;
14 |
15 | public class SqlBrowserFXAppManager {
16 |
17 | public final static String INTERNAL_DB_PATH = "./sqlbrowser.db";
18 |
19 | private static final SqlConnector SQL_CONNECTOR = new SqliteConnector(INTERNAL_DB_PATH);
20 | private static final List DSQL_PANES = new ArrayList<>();
21 | private static final List SQL_PANES = new ArrayList<>();
22 | private static final List DB_TREE_VIEWS = new ArrayList<>();
23 | private static String DB_TYPE = "sqlite";
24 |
25 | public static SqlConnector getConfigSqlConnector() {
26 | return SQL_CONNECTOR;
27 | }
28 |
29 | public static void registerDSqlPane(DSqlPane sqlPane) {
30 | DSQL_PANES.add(sqlPane);
31 | DB_TREE_VIEWS.forEach(DDBTreeView::populateSqlPanesMenu);
32 | }
33 |
34 | public static void registerSqlPane(SqlPane sqlPane) {
35 | SQL_PANES.add(sqlPane);
36 | DB_TREE_VIEWS.forEach(DDBTreeView::populateSqlPanesMenu);
37 | }
38 |
39 | public static List getActiveSqlPanes() {
40 | List sqlPanes = DSQL_PANES.stream().map(sp -> (SqlPane) sp).collect(Collectors.toList());
41 | sqlPanes.addAll(SQL_PANES);
42 | return sqlPanes.stream().filter(Objects::nonNull).collect(Collectors.toList());
43 | }
44 |
45 | public static long getActiveSqlCodeAreasNum() {
46 | return DSQL_PANES.stream().filter(x -> x.getSqlCodeAreaRef() != null).count();
47 | }
48 |
49 | public static DSqlConsolePane getFirstActiveDSqlConsolePane() {
50 | DSqlPane activeSqlPane = DSQL_PANES.stream()
51 | .filter(sqlPane -> sqlPane.getSqlConsolePane() != null)
52 | .findFirst()
53 | .orElse(null);
54 |
55 | if (activeSqlPane != null) {
56 | return activeSqlPane.getSqlConsolePane();
57 | }
58 |
59 | return null;
60 | }
61 |
62 | public static void unregisterDSqlPane(DSqlPane sqlPane) {
63 | DSQL_PANES.remove(sqlPane);
64 | DB_TREE_VIEWS.forEach(DDBTreeView::populateSqlPanesMenu);
65 | }
66 |
67 | public static String getDBtype() {
68 | return DB_TYPE;
69 | }
70 |
71 | public static void setDBtype(String type) {
72 | DB_TYPE = type;
73 | }
74 |
75 | public static void registerDDBTreeView(DDBTreeView treeView) {
76 | DB_TREE_VIEWS.add(treeView);
77 | }
78 |
79 | public static void unregisterDDBTreeView(DDBTreeView treeView) {
80 | DB_TREE_VIEWS.remove(treeView);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/DbCash.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import java.util.HashMap;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | public class DbCash {
8 | private static final Map SCHEMAS_MAP = new HashMap<>();
9 | private static final Map TABLES_MAP = new HashMap<>();
10 |
11 |
12 |
13 | public static synchronized String getSchemaFor(String table) {
14 | return SCHEMAS_MAP.get(table);
15 | }
16 |
17 | public static synchronized void addSchemaFor(String table, String schema) {
18 | SCHEMAS_MAP.put(table, schema);
19 | }
20 |
21 | public static synchronized void addTable(SqlTable table) {
22 | TABLES_MAP.put(table.getName(), table);
23 | }
24 |
25 | public static synchronized SqlTable getTable(String table) {
26 | return TABLES_MAP.get(table);
27 | }
28 |
29 | public static List getAllTableNames() {
30 | return TABLES_MAP.values().stream().map(SqlTable::getName).toList();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/PostgreSqlConnector.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import java.sql.Connection;
4 | import java.sql.Date;
5 | import java.sql.SQLException;
6 | import java.sql.Timestamp;
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.List;
10 |
11 | import javax.sql.DataSource;
12 |
13 | import org.apache.commons.dbcp2.BasicDataSource;
14 | import org.slf4j.LoggerFactory;
15 |
16 | import gr.sqlbrowserfx.LoggerConf;
17 |
18 | public class PostgreSqlConnector extends SqlConnector {
19 |
20 | public PostgreSqlConnector(String url, String database, String user, String password) {
21 | super("org.postgresql.Driver", url, user, password);
22 |
23 | }
24 |
25 | @Override
26 | protected DataSource initDatasource() {
27 | BasicDataSource dbcp2DataSource = new BasicDataSource();
28 | dbcp2DataSource.setDriverClassName(this.getDriver());
29 | dbcp2DataSource.setUrl(this.getUrl());
30 | dbcp2DataSource.setUsername(this.getUser());
31 | dbcp2DataSource.setPassword(this.getPassword());
32 | dbcp2DataSource.setInitialSize(4);
33 | dbcp2DataSource.setMaxTotal(4);
34 |
35 | return dbcp2DataSource;
36 | }
37 |
38 | @Override
39 | public Object castToDBType(SqlTable table, String label, String value) {
40 | Object actualValue;
41 | if (table.getColumnsMap().get(label).contains("int") && value != null && !value.isEmpty()) {
42 | actualValue = Integer.parseInt(value);
43 | } else if (table.getColumnsMap().get(label).equals("numeric") && value != null && !value.isEmpty()) {
44 | actualValue = Double.parseDouble(value);
45 | }
46 | else if (table.getColumnsMap().get(label).contains("bool") && value != null && !value.isEmpty()) {
47 | actualValue = Boolean.parseBoolean(value);
48 | }
49 | else if (table.getColumnsMap().get(label).contains("date") && value != null && !value.isEmpty()) {
50 | actualValue = Date.valueOf(value);
51 | }
52 | else if (table.getColumnsMap().get(label).contains("stamp") && value != null && !value.isEmpty()) {
53 | actualValue = Timestamp.valueOf(value);
54 | }
55 | else {
56 | actualValue = value;
57 | }
58 | return actualValue;
59 | }
60 |
61 |
62 | @Override
63 | public String getContentsQuery() {
64 | return "select tb.table_name, tb.table_type from INFORMATION_SCHEMA.tables as tb WHERE tb.table_schema = ANY (current_schemas(false))"
65 | + " union "
66 | + "select indexname as table_name , 'INDEX'as table_type from pg_indexes where schemaname = 'public'";
67 | }
68 |
69 | @Override
70 | public String getDbSchema() {
71 | return "public";
72 | }
73 |
74 | @Override
75 | public void getTriggers(String table, ResultSetAction action) throws SQLException {
76 | String query =
77 | "select event_object_schema as table_schema, "
78 | + " event_object_table as table_name, "
79 | + " trigger_schema, "
80 | + " trigger_name as TRIGGER_NAME, "
81 | + " string_agg(event_manipulation, ',') as event, "
82 | + " action_timing as activation, "
83 | + " action_condition as condition, "
84 | + " action_statement as ACTION_STATEMENT "
85 | + "from information_schema.triggers "
86 | + "where event_object_table = ? "
87 | + "group by 1,2,3,4,6,7,8 "
88 | + "order by table_schema, "
89 | + " table_name;";
90 | this.executeQuery(query, Arrays.asList(table), action);
91 |
92 | }
93 |
94 | @Override
95 | public void getSchema(String name, ResultSetAction action) throws SQLException {
96 | this.executeQuery(
97 | "select table_name, view_definition as schema from INFORMATION_SCHEMA.views "
98 | + "WHERE table_schema = ANY (current_schemas(false)) and table_name = ?",
99 | Arrays.asList(name), action);
100 | }
101 |
102 | @Override
103 | public String getTableSchemaColumn() {
104 | return "schema";
105 | }
106 |
107 | @Override
108 | public String getViewSchemaColumn() {
109 | return "schema";
110 | }
111 |
112 | @Override
113 | public String getIndexSchemaColumn() {
114 | return "schema";
115 | }
116 |
117 | @Override
118 | public void commitAll() {
119 | BasicDataSource dataSource = (BasicDataSource) this.getDataSource();
120 | List connections = new ArrayList<>();
121 | Connection conn = null;
122 | try {
123 | int activeConnections = dataSource.getNumIdle();
124 | for (int i = 0; i < activeConnections; i++) {
125 | conn = dataSource.getConnection();
126 | conn.commit();
127 | connections.add(conn);
128 | }
129 | LoggerFactory.getLogger(LoggerConf.LOGGER_NAME).debug(activeConnections + " connections commited");
130 | } catch (SQLException e) {
131 | LoggerFactory.getLogger(LoggerConf.LOGGER_NAME).error("Failed to commit changes , about to rollback", e);
132 | this.rollbackQuietly(conn);
133 | }
134 | for (Connection conn2 : connections)
135 | this.closeQuietly(conn2);
136 | }
137 |
138 | @Override
139 | public void rollbackAll() {
140 | BasicDataSource dataSource = (BasicDataSource) this.getDataSource();
141 | List connections = new ArrayList<>();
142 | Connection conn = null;
143 | try {
144 | int activeConnections = dataSource.getNumIdle();
145 | for (int i = 0; i < activeConnections; i++) {
146 | conn = dataSource.getConnection();
147 | conn.rollback();
148 | connections.add(conn);
149 | }
150 | } catch (SQLException e) {
151 | LoggerFactory.getLogger(LoggerConf.LOGGER_NAME).error("Failed to rollback changes", e);
152 | }
153 | for (Connection conn2 : connections)
154 | this.closeQuietly(conn2);
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/ResultSetAction.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import java.sql.ResultSet;
4 | import java.sql.SQLException;
5 |
6 | @FunctionalInterface
7 | public interface ResultSetAction {
8 |
9 | public void onResultSet(ResultSet rset) throws SQLException;
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/SqlTable.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import gr.sqlbrowserfx.LoggerConf;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.sql.ResultSetMetaData;
7 | import java.sql.SQLException;
8 | import java.util.ArrayList;
9 | import java.util.LinkedHashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 | import java.util.Set;
13 |
14 | public class SqlTable {
15 |
16 | private String name;
17 | private String primaryKey;
18 | private List foreignKeys;
19 | private List relatedTables;
20 | private LinkedHashMap columnsMap;
21 |
22 | public SqlTable(ResultSetMetaData rsmd) {
23 |
24 | foreignKeys = new ArrayList<>();
25 | try {
26 | name = rsmd.getTableName(1);
27 | columnsMap = new LinkedHashMap<>();
28 | for (int i = 1; i <= rsmd.getColumnCount(); i++) {
29 | columnsMap.put(rsmd.getColumnLabel(i), rsmd.getColumnTypeName(i));
30 | }
31 |
32 | } catch (SQLException e) {
33 | LoggerFactory.getLogger(LoggerConf.LOGGER_NAME).error(e.getMessage(), e);
34 | }
35 | }
36 |
37 | public SqlTable(String tableName, ResultSetMetaData rsmd) {
38 | this(rsmd);
39 | name = tableName;
40 | }
41 |
42 | public String getName() {
43 | return name;
44 | }
45 |
46 | public void setName(String name) {
47 | this.name = name;
48 | }
49 |
50 | public Map getColumnsMap() {
51 | return columnsMap;
52 | }
53 |
54 | public void setColumnsMap(LinkedHashMap columns) {
55 | this.columnsMap = columns;
56 | }
57 |
58 | /*
59 | * Returns tables's primary key , IMPORTANT in case of a composite
60 | * key it returns a comma separated string with the keys
61 | *
62 | */
63 | public String getPrimaryKey() {
64 | return primaryKey;
65 | }
66 |
67 | public void setPrimaryKey(String primaryKey) {
68 | this.primaryKey = primaryKey;
69 | }
70 |
71 | public Set getColumns() {
72 | return columnsMap.keySet();
73 | }
74 |
75 | public List getForeignKeys() {
76 | return foreignKeys;
77 | }
78 |
79 | public void setForeignKeys(List foreignKeys) {
80 | this.foreignKeys = foreignKeys;
81 | }
82 |
83 | public void addForeignKey(String foreignKey) {
84 | foreignKeys.add(foreignKey);
85 | }
86 |
87 | public boolean isForeignKey(String key) {
88 | for (String foreignKey : foreignKeys) {
89 | if (key.equals(foreignKey)) {
90 | return true;
91 | }
92 | }
93 | return false;
94 | }
95 |
96 | public boolean isPrimaryKey(String key) {
97 | return (primaryKey != null && primaryKey.equals(key));
98 | }
99 |
100 | public String columnsToString() {
101 | StringBuilder result = new StringBuilder();
102 | for (String column : columnsMap.keySet()) {
103 | result.append(column).append(",");
104 | }
105 | return result.substring(0, result.length() - 1);
106 | }
107 |
108 | public List getRelatedTables() {
109 | return this.relatedTables;
110 | }
111 |
112 | public void setRelatedTables(List relatedTables) {
113 | this.relatedTables = relatedTables;
114 | }
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/StatementAction.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import java.sql.Statement;
4 |
5 | @FunctionalInterface
6 | public interface StatementAction {
7 |
8 | void onStatement(Statement stmt);
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/gr/sqlbrowserfx/conn/UpdateQuery.java:
--------------------------------------------------------------------------------
1 | package gr.sqlbrowserfx.conn;
2 |
3 | import java.util.List;
4 |
5 | public class UpdateQuery {
6 |
7 | private String query;
8 | List