<commit_before><?php
/**
 * SQL client - the main class.
 *
 * Classes this relies on:
 *  - SimpleReadline
 *  - HistoryStorage
 *
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright (C) 2010 <NAME>
 */
class InteractiveSqlTerminal {

	/**
	 * @var $db DbBackend object for the backend/database
	 */
	private $db;

	/**
	 * @var $tty_saved Stores stty string of saved terminal settings
	 */
	private $tty_saved = '';

	/**
	 * @var $history_stage HistoryStorage class that saves command history to a file
	 */
	private $history_storage;
	
	/**
	 * @var $shell SimpleReadline object
	 */
	private $shell;

	/**
	 * @var $line_buffer line output buffer
	 */
	private $line_buffer = array();
	
	/**
	 * Constructor - initialises Matrix DAL and attempts to connect to database
	 *
	 * @param $backend name of backend plugin to use to connect
	 */
	public function __construct($backend) {

		$this->resetTerminal(true);

		// Instantiate database backend plugin
		$this->db = new DbBackend($backend);

		// Instantiate/initialise stuff
		$this->shell = new SimpleReadline();

		// History storage
		if (!isset($_ENV['HOME'])) {
			$history_storage_file = '/tmp';
		} else {
			$history_storage_file = $_ENV['HOME'];
		}
		$this->history_storage = new HistoryStorage($history_storage_file . '/.matrixsqlclient_history', true);
		$this->shell->history = $this->history_storage->getData();
	}
	
	/**
	 * Destructor function - should restore terminal settings
	 */
	public function __destruct() {
		$this->restoreTerminal();
	}

	/**
	 * Connects the db backend
	 *
	 * @param $dsn connection string for database
	 */
	public function connect($dsn) {
		$this->db->connect($dsn);
	}

	/**
	 * Starts the main interactive terminal
	 */
	public function run() {

		$prompt = '=# ';
		$sql = '';

		ob_start();
		echo "Welcome to matrixsqlclient (alpha";
		if (!empty($GLOBALS['rev'])) echo ", rev " . $GLOBALS['rev'];
		echo "), the interative database terminal in PHP.";
		echo "\n\nYou are now connected.";
		echo "\nDatabase type: " . $this->db->getDbType() . $this->db->getDbVersion() . ".\n";
		ob_end_flush();
		
		while (1) {
		
			// Prompt for input
			$line = $this->shell->readline($this->db->getDbName() . $prompt);

			// Exits
			if ((substr(trim($line), 0, 4) == 'exit') || (substr(trim($line), 0, 4) == 'quit') || (substr(trim($line), 0, 2) == '\q')) {
				echo "\n";
				exit;
			}
			if (substr($line, strlen($line)-1, strlen($line)) === chr(4)) {
				echo "\q\n";
				exit;
			}

			if (strlen($line) > 0) {
				// Add this command to the history
				$this->shell->readline_add_history(strtr($line, "\n", " "));
			}

			// CTRL-C cancels any current query
			if (ord(substr($line, strlen($line)-1, strlen($line))) === 3) {
				$sql = '';
				$line = '';
				$prompt = '=# ';
				continue;
			}
		
			$sql .= "\n" . $line;

			// If the current sql string buffer has a semicolon in it, we're ready to run
			// the SQL!
			if (strpos($sql, ';')) {

				echo "\n";

				$sql = trim($sql);

				try {
					// Run the SQL
					$source_data = $this->db->execute($sql);
				}
				catch (Exception $e) {
					echo "\n" . $e->getMessage() . "\n";

					// Reset the prompt cause its a new query
					$prompt = '=# ';
					$sql = '';

					continue;
				}

				// Find out what type of query this is and what to do with it
				if (strtoupper(substr($sql, 0, 6)) == "UPDATE") {
				    echo "UPDATE " . count($source_data);
				}
				elseif ((strtoupper(substr($sql, 0, 5)) == "BEGIN") ||
				        (strtoupper(substr($sql, 0, 5)) == "START TRANSACTION")) {
				    echo "BEGIN";
				}
				elseif ((strtoupper(substr($sql, 0, 5)) == "ABORT") ||
				        (strtoupper(substr($sql, 0, 5)) == "ROLLBACK")) {
				    echo "ROLLBACK";
				}
				elseif (strtoupper(substr($sql, 0, 6)) == "COMMIT") {
				    echo "COMMIT";
				}
				// SELECTs and default
				else {

					// Only render the table if rows were returned
					if (!empty($source_data)) {

						// Render the table
						$table = new ArrayToTextTable($source_data);
						$table->showHeaders(true);

						$this->addToLinesBuffer(explode("\n", $table->render(true)));
					}

					// Build count summary (at end of table) and add to line buffer
					$count_str = "(" . count($source_data) . " row";
					if (count($source_data) !== 1) $count_str .= "s";
					$count_str .= ")";

					$this->addToLinesBuffer(array($count_str));

					// Output the data
					$this->printLines();
				}
		
				// Reset the prompt cause its a new query
				$prompt = '=# ';
				$sql = '';
		
			} elseif (strlen(trim($sql)) > 0) {<commit_msg>Add line break to table head instead; mainly to make the output look better when there's 0 rows.<commit_after><?php
/**
 * SQL client - the main class.
 *
 * Classes this relies on:
 *  - SimpleReadline
 *  - HistoryStorage
 *
 * @author <NAME> <<EMAIL>>
 * @copyright Copyright (C) 2010 <NAME>
 */
class InteractiveSqlTerminal {

	/**
	 * @var $db DbBackend object for the backend/database
	 */
	private $db;

	/**
	 * @var $tty_saved Stores stty string of saved terminal settings
	 */
	private $tty_saved = '';

	/**
	 * @var $history_stage HistoryStorage class that saves command history to a file
	 */
	private $history_storage;
	
	/**
	 * @var $shell SimpleReadline object
	 */
	private $shell;

	/**
	 * @var $line_buffer line output buffer
	 */
	private $line_buffer = array();
	
	/**
	 * Constructor - initialises Matrix DAL and attempts to connect to database
	 *
	 * @param $backend name of backend plugin to use to connect
	 */
	public function __construct($backend) {

		$this->resetTerminal(true);

		// Instantiate database backend plugin
		$this->db = new DbBackend($backend);

		// Instantiate/initialise stuff
		$this->shell = new SimpleReadline();

		// History storage
		if (!isset($_ENV['HOME'])) {
			$history_storage_file = '/tmp';
		} else {
			$history_storage_file = $_ENV['HOME'];
		}
		$this->history_storage = new HistoryStorage($history_storage_file . '/.matrixsqlclient_history', true);
		$this->shell->history = $this->history_storage->getData();
	}
	
	/**
	 * Destructor function - should restore terminal settings
	 */
	public function __destruct() {
		$this->restoreTerminal();
	}

	/**
	 * Connects the db backend
	 *
	 * @param $dsn connection string for database
	 */
	public function connect($dsn) {
		$this->db->connect($dsn);
	}

	/**
	 * Starts the main interactive terminal
	 */
	public function run() {

		$prompt = '=# ';
		$sql = '';

		ob_start();
		echo "Welcome to matrixsqlclient (alpha";
		if (!empty($GLOBALS['rev'])) echo ", rev " . $GLOBALS['rev'];
		echo "), the interative database terminal in PHP.";
		echo "\n\nYou are now connected.";
		echo "\nDatabase type: " . $this->db->getDbType() . $this->db->getDbVersion() . ".\n";
		ob_end_flush();
		
		while (1) {
		
			// Prompt for input
			$line = $this->shell->readline($this->db->getDbName() . $prompt);

			// Exits
			if ((substr(trim($line), 0, 4) == 'exit') || (substr(trim($line), 0, 4) == 'quit') || (substr(trim($line), 0, 2) == '\q')) {
				echo "\n";
				exit;
			}
			if (substr($line, strlen($line)-1, strlen($line)) === chr(4)) {
				echo "\q\n";
				exit;
			}

			if (strlen($line) > 0) {
				// Add this command to the history
				$this->shell->readline_add_history(strtr($line, "\n", " "));
			}

			// CTRL-C cancels any current query
			if (ord(substr($line, strlen($line)-1, strlen($line))) === 3) {
				$sql = '';
				$line = '';
				$prompt = '=# ';
				continue;
			}
		
			$sql .= "\n" . $line;

			// If the current sql string buffer has a semicolon in it, we're ready to run
			// the SQL!
			if (strpos($sql, ';')) {

				echo "\n";

				$sql = trim($sql);

				try {
					// Run the SQL
					$source_data = $this->db->execute($sql);
				}
				catch (Exception $e) {
					echo "\n" . $e->getMessage() . "\n";

					// Reset the prompt cause its a new query
					$prompt = '=# ';
					$sql = '';

					continue;
				}

				// Find out what type of query this is and what to do with it
				if (strtoupper(substr($sql, 0, 6)) == "UPDATE") {
				    echo "UPDATE " . count($source_data);
				}
				elseif ((strtoupper(substr($sql, 0, 5)) == "BEGIN") ||
				        (strtoupper(substr($sql, 0, 5)) == "START TRANSACTION")) {
				    echo "BEGIN";
				}
				elseif ((strtoupper(substr($sql, 0, 5)) == "ABORT") ||
				        (strtoupper(substr($sql, 0, 5)) == "ROLLBACK")) {
				    echo "ROLLBACK";
				}
				elseif (strtoupper(substr($sql, 0, 6)) == "COMMIT") {
				    echo "COMMIT";
				}
				// SELECTs and default
				else {

					$this->addToLinesBuffer(array(''));

					// Only render the table if rows were returned
					if (!empty($source_data)) {

						// Render the table
						$table = new ArrayToTextTable($source_data);
						$table->showHeaders(true);

						$this->addToLinesBuffer(explode("\n", $table->render(true)));
					}

					// Build count summary (at end of table) and add to line buffer
					$count_str = "(" . count($source_data) . " row";
					if (count($source_data) !== 1) $count_str .= "s";
					$count_str .= ")";

					$this->addToLinesBuffer(array($count_str));

					// Output the data
					$this->printLines();
				}
		
				// Reset the prompt cause its a new query
				$prompt = '=# ';
				$sql = '';
		
			} elseif (strlen(trim($sql)) > 0) {
{'fraction_non_alphanumeric': 0.1778375470683163, 'fraction_numerical': 0.006562668101129639, 'mean_word_length': 2.713943268078306, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3814336', 'n_tokens_mistral': 3784, 'n_tokens_neox': 3032, 'n_words': 832}