package burp;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Handles SQLite database access
 */
public class Database {
	private Connection conn = null;
	private PreparedStatement pstmt = null; //TODO: prepared statements for inserting data
	private PrintWriter stdErr;

	private String sql_tableCheck = "SELECT name FROM sqlite_master WHERE type='table' AND name='params';";
	private String sql_dropTable = "DROP TABLE IF EXISTS params;";
	//TODO: design table schemas
	// REF: https://www.sqlite.org/datatype3.html
	private String sql_createTable = "CREATE TABLE params (name TEXT PRIMARY KEY NOT NULL, hash TEXT NOT NULL);";

	public Database(IBurpExtenderCallbacks c) {
		stdErr = new PrintWriter(c.getStderr(), true);
		try {
			// the following line loads the JDBC Driver
			Class.forName("org.sqlite.JDBC");
		} catch (ClassNotFoundException e) {
			this.stdErr.println(e.getMessage());
		}
	}

	public boolean close() {
		try {
			if (this.conn != null)
				this.conn.close();
			return true;
		} catch (SQLException e) {
			this.stdErr.println(e.getMessage());
			return false;
		}
	}

	/**
	 * TODO: this might need some tweaking
	 */
	protected void finalize() throws Throwable {
		try {
			if (this.conn != null)
				conn.close();
		}
		finally {
			super.finalize();
		}
	}

	/**
	 * TODO: drop/create all necessary tables (params, hashes, etc.)
	 */
	public boolean init() {
		Statement stmt = null;
		try {
			if (this.conn == null) {
				this.conn = DriverManager
						.getConnection("jdbc:sqlite:burp-hash.db");
			}
			stmt = conn.createStatement();
			stmt.setQueryTimeout(30);
			stmt.executeUpdate(this.sql_dropTable);
			stmt.executeUpdate(this.sql_createTable);
			return true;
		} catch (SQLException e) {
			this.stdErr.println(e.getMessage());
			return false;
		}
	}

	/**
	 * TODO: verify presence of all tables? (params, hashes, etc.)
	 *
	 * Another option would be to simply do away with this method altogether
	 * and instead perform "CREATE TABLE IF NOT EXISTS" operations for all
	 * tables every time the extension loads.
	 */
	public boolean verify() {
		Statement stmt = null;
		ResultSet rs = null;

		try {
			if (this.conn == null) {
				this.conn = DriverManager
						.getConnection("jdbc:sqlite:burp-hash.db");
			}
			stmt = conn.createStatement();
			stmt.setQueryTimeout(30);
			rs = stmt.executeQuery(sql_tableCheck);
			boolean x = false;
			while (rs.next()) {
				x = true;
			}
			return x;
		} catch (SQLException e) {
			this.stdErr.println(e.getMessage());
			return false;
		}
	}

	/**
	 * TODO: add methods for storing/retrieving data
	 */
}
@@ -297,27 +297,94 @@
  Con
-nection conn = null
+fig config;%0A%09private Connection conn = null;%0A%09private IBurpExtenderCallbacks callbacks
 ;%0A%09p
@@ -500,32 +500,89 @@
 dErr;%0A%0A%09private 
+final String connPrefix = %22jdbc:sqlite:%22;%0A%09private final 
 String sql_table
@@ -662,32 +662,38 @@
 ms';%22;%0A%09private 
+final 
 String sql_dropT
@@ -817,16 +817,22 @@
 private 
+final 
 String s
@@ -943,17 +943,16 @@
 atabase(
-I
 BurpExte
@@ -959,70 +959,111 @@
 nder
-Callbacks c) %7B%0A%09%09stdErr = new PrintWriter(c
+ b) %7B%0A%09%09this.callbacks = b.getCallbacks();%0A%09%09this.config = b.getConfig();%0A%09%09this.stdErr = b
 .getStd
-e
+E
 rr()
-, true)
 ;%0A%09%09
@@ -1617,32 +1617,315 @@
 lize();%0A%09%09%7D%0A%09%7D%0A%0A
+%09private Connection getConnection() %7B%0A%09%09Connection connection;%0A%09%09try %7B%0A%09%09%09connection = DriverManager.getConnection(this.connPrefix%0A%09%09%09%09%09+ this.config.databaseFilename);%0A%09%09%7D catch (SQLException e) %7B%0A%09%09%09this.stdErr.println(e.getMessage());%0A%09%09%09return null;%0A%09%09%7D%0A%09%09return connection;%0A%09%7D%0A%0A
 %09/**%0A%09 * TODO: d
@@ -2090,69 +2090,27 @@
 n = 
-DriverManager%0A%09%09%09%09%09%09.getConnection(%22jdbc:sqlite:burp-hash.db%22
+this.getConnection(
 );%0A%09
@@ -2773,69 +2773,27 @@
 n = 
-DriverManager%0A%09%09%09%09%09%09.getConnection(%22jdbc:sqlite:burp-hash.db%22
+this.getConnection(
 );%0A%09

refactor database connections