This repository has been archived by the owner on Mar 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 74ce2d6
Showing
12 changed files
with
701 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.