Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
Fully working demo
Browse files Browse the repository at this point in the history
  • Loading branch information
dikayx committed Mar 14, 2022
0 parents commit 74ce2d6
Show file tree
Hide file tree
Showing 12 changed files with 701 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build

# Ignore local editor settings
.idea

# System trash files
.DS_Store
33 changes: 33 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/7.4.1/userguide/building_java_projects.html
*/

plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
}

repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}

dependencies {
// Use JUnit test framework.
testImplementation 'junit:junit:4.13.2'

// This dependency is used by the application.
implementation 'com.google.guava:guava:30.1.1-jre'

// SQLite connector
implementation 'org.xerial:sqlite-jdbc:3.34.0'
}

application {
// Define the main class for the application.
mainClass = 'SQLite.Viewer.App'
}
7 changes: 7 additions & 0 deletions app/src/main/java/SQLite/Viewer/ApplicationRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package SQLite.Viewer;

public class ApplicationRunner {
public static void main(String[] args) {
new SQLiteViewer();
}
}
34 changes: 34 additions & 0 deletions app/src/main/java/SQLite/Viewer/DataTableModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package SQLite.Viewer;

import javax.swing.table.AbstractTableModel;
import java.util.Map;

public class DataTableModel extends AbstractTableModel {
private final String[] columns;
private final Map<Integer, Object[]> data;

public DataTableModel(String[] columns, Map<Integer, Object[]> data) {
this.columns = columns;
this.data = data;
}

@Override
public String getColumnName(int column) {
return columns[column];
}

@Override
public int getRowCount() {
return data.size();
}

@Override
public int getColumnCount() {
return columns.length;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data.get(rowIndex)[columnIndex];
}
}
74 changes: 74 additions & 0 deletions app/src/main/java/SQLite/Viewer/Driver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package SQLite.Viewer;

import org.sqlite.SQLiteDataSource;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Driver implements AutoCloseable {

private Connection connection;

public static final String SQL_ALL_ROWS = "SELECT * FROM %s;";
private static final String SQL_FIND_ALL_TABLES =
"SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE 'sqlite_%';";

public Driver(String fileName) throws SQLException {
connect(fileName);
}

// Connect to a selected database
protected void connect(String fileName) throws SQLException {
// SQLite default url
String url = "jdbc:sqlite:%s";
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl(String.format(url, fileName));
connection = dataSource.getConnection();
}

// Retrieve all tables of a specific database
protected List<String> getAllTables() throws SQLException {
List<String> tableNames = new ArrayList<>();
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(SQL_FIND_ALL_TABLES);
while (resultSet.next()) {
String name = resultSet.getString("name");
tableNames.add(name);
}
return tableNames;
}
}

// Execute specified query
protected DataTableModel runQuery(String query, String table) throws SQLException {
try (Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(query);
ResultSetMetaData metaData = resultSet.getMetaData();
// Retrieve columns
int columnCount = metaData.getColumnCount();
String[] columns = new String[columnCount];
for (int i = 0; i < metaData.getColumnCount(); i++) {
columns[i] = metaData.getColumnName(i + 1);
}
// Retrieve row
Map<Integer, Object[]> data = new HashMap<>();
int i = 0;
while (resultSet.next()) {
Object[] row = new Object[columnCount];
for (int j = 0; j < columnCount; j++) {
row[j] = resultSet.getObject(j + 1);
}
data.put(i++, row);
}
return new DataTableModel(columns, data);
}
}

@Override
public void close() throws Exception {
connection.close();
}
}
189 changes: 189 additions & 0 deletions app/src/main/java/SQLite/Viewer/SQLiteViewer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package SQLite.Viewer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.Objects;

public class SQLiteViewer extends JFrame {

private String fileName;

public SQLiteViewer() {
// Basic window settings
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(595, 700);
setLayout(new BorderLayout());
setResizable(true);
setLocationRelativeTo(null);
setTitle("SQLite Viewer");
// Initialize main window components
initComponents();
// Render window content
setVisible(true);
}

private void initComponents() {
// Components
JTextField fileNameTextField = new JTextField();
fileNameTextField.setName("FileNameTextField");
fileNameTextField.setColumns(35);

JButton openFileButton = new JButton("Open");
openFileButton.setName("OpenFileButton");

JComboBox<String> tablesComboBox = new JComboBox<>();
tablesComboBox.setName("TablesComboBox");

JTextArea queryTextArea = new JTextArea();
queryTextArea.setName("QueryTextArea");
queryTextArea.setRows(5);
queryTextArea.setColumns(40);
queryTextArea.setEnabled(false);
JScrollPane queryTextScroll = new JScrollPane(queryTextArea);

JButton executeButton = new JButton("Execute");
executeButton.setName("ExecuteQueryButton");
executeButton.setEnabled(false);

JTable table = new JTable();
table.setName("Table");
table.setFillsViewportHeight(true);
JScrollPane tableScrollPane = new JScrollPane(table);

// Menu bar
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);

// File menu
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F); // Only works on win32

JMenuItem loadMenuItem = new JMenuItem("Load file...");
loadMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()));

JMenuItem quitMenuItem = new JMenuItem("Quit");
quitMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx()));
quitMenuItem.addActionListener(actionEvent -> {
System.exit(0);
});
quitMenuItem.setName("MenuExit");

// Add file menu components
fileMenu.add(loadMenuItem);
fileMenu.addSeparator();
fileMenu.add(quitMenuItem);

// SQL selection menu
JMenu sqlMenu = new JMenu("Select");

JMenuItem sqliteMenuItem = new JMenuItem("SQLite");

sqlMenu.add(sqliteMenuItem);

// Add to menu bar
menuBar.add(fileMenu);
menuBar.add(sqlMenu);

// Place components
JPanel topPanel = new JPanel(new GridLayout(2, 1));
add(topPanel, BorderLayout.PAGE_START);

JPanel selectionPanel = new JPanel(new GridLayout(2, 1));

JPanel selectFilePanel = new JPanel();
selectFilePanel.setLayout(new FlowLayout(FlowLayout.LEADING));
selectFilePanel.add(new JLabel("Locate the SQLite *.db file:"));
selectFilePanel.add(fileNameTextField);
selectFilePanel.add(openFileButton);
selectFilePanel.setBorder(BorderFactory.createTitledBorder("Select file"));

JPanel selectTablePanel = new JPanel(new GridLayout(2, 0));
selectTablePanel.add(new JLabel("Please select a table from the database:"));
selectTablePanel.add(tablesComboBox);
selectTablePanel.setBorder(BorderFactory.createTitledBorder("Select table"));

selectionPanel.add(selectFilePanel);
selectionPanel.add(selectTablePanel);

JPanel centerPanel = new JPanel(new GridLayout(1, 0));
add(centerPanel, BorderLayout.CENTER);

JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
queryPanel.add(queryTextScroll);
queryPanel.add(executeButton);
queryPanel.setBorder(BorderFactory.createTitledBorder("Run query"));

JPanel tablePanel = new JPanel(new GridLayout(1, 0));
tablePanel.add(tableScrollPane);
tablePanel.setBorder(BorderFactory.createTitledBorder("Results"));

// Add panels to main window
topPanel.add(selectionPanel);
topPanel.add(queryPanel);
centerPanel.add(tablePanel);

// Action Listeners
loadMenuItem.addActionListener(actionEvent -> {
JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
fileNameTextField.setText(""); // Clear text
fileName = fileChooser.getSelectedFile().toString();
fileNameTextField.setText(fileChooser.getSelectedFile().toString());
}
});
openFileButton.addActionListener(actionEvent -> {
Path filePath = Paths.get(fileNameTextField.getText());
if (!Objects.equals(fileNameTextField.getText(), "") && Files.exists(filePath)) {
try (Driver driver = new Driver(fileName)) {
tablesComboBox.removeAllItems();
driver.getAllTables().forEach(tablesComboBox::addItem);
queryTextArea.setText(String.format(Driver.SQL_ALL_ROWS, tablesComboBox.getSelectedItem()));
// Enable buttons
queryTextArea.setEnabled(true);
executeButton.setEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
} else {
tablesComboBox.removeAllItems();
queryTextArea.setText(null);
queryTextArea.setEnabled(false);
executeButton.setEnabled(false);
JOptionPane.showMessageDialog(
new Frame(),
"File doesn't exist!",
"File error",
JOptionPane.ERROR_MESSAGE
);
}
});
tablesComboBox.addItemListener(actionEvent -> {
queryTextArea.setText(String.format(Driver.SQL_ALL_ROWS, actionEvent.getItem().toString()));
});
executeButton.addActionListener(actionEvent -> {
try (Driver driver = new Driver(fileNameTextField.getText())) {
DataTableModel tableModel = driver.runQuery(
queryTextArea.getText(),
(String) tablesComboBox.getSelectedItem()
);
table.setModel(tableModel);
} catch (SQLException e) {
JOptionPane.showMessageDialog(
new Frame(),
e.getMessage(),
"SQL error",
JOptionPane.ERROR_MESSAGE
);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
14 changes: 14 additions & 0 deletions app/src/test/java/SQLite/Viewer/AppTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package SQLite.Viewer;

import org.junit.Test;
import static org.junit.Assert.*;

public class AppTest {
@Test public void appHasAGreeting() {
App classUnderTest = new App();
assertNotNull("app should have a greeting", classUnderTest.getGreeting());
}
}
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 74ce2d6

Please sign in to comment.