diff --git a/index.php b/index.php index bf3cad6..dcc54c1 100644 --- a/index.php +++ b/index.php @@ -75,13 +75,23 @@ if( ! class_exists('pdo')) // -------------------------------------------------------------------------- -// Convert Errors to Exceptions -// Do this after the two compatibility checks for cleaner output +/** + * Error handler to convert errors to exceptions + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @throws ErrorException + */ function exception_error_handler($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } -set_error_handler("exception_error_handler"); + +// Do this after the two compatibility checks for cleaner output +// Note that this will throw exceptions on notices +set_error_handler("exception_error_handler", -1); // -------------------------------------------------------------------------- @@ -111,7 +121,7 @@ $path = BASE_DIR . "/db/drivers/"; foreach(pdo_drivers() as $d) { - //Favor ibase over PDO firebird + //Favor ibase/fbird over PDO firebird if ($d === 'firebird') { continue; diff --git a/sys/db/drivers/mysql/mysql_driver.php b/sys/db/drivers/mysql/mysql_driver.php index 0bdbfee..d485be2 100644 --- a/sys/db/drivers/mysql/mysql_driver.php +++ b/sys/db/drivers/mysql/mysql_driver.php @@ -31,6 +31,10 @@ class MySQL extends DB_PDO { */ public function __construct($dsn, $username=null, $password=null, $options=array()) { + $options = array_merge($options, array( + PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF-8 COLLATE 'UTF-8'", + )); + parent::__construct("mysql:$dsn", $username, $password, $options); $class = __CLASS__.'_sql'; diff --git a/sys/db/query_builder.php b/sys/db/query_builder.php index cb79fd2..4de7027 100644 --- a/sys/db/query_builder.php +++ b/sys/db/query_builder.php @@ -94,6 +94,7 @@ class Query_Builder { { $dsn .= ";port={$params->port}"; } + break; case "sqlite": @@ -105,6 +106,9 @@ class Query_Builder { break; } + // Set the charset + //$dsn .= ";charset=utf-8"; + // Create the database connection if ( ! empty($params->user)) { @@ -114,12 +118,12 @@ class Query_Builder { { $this->db = new $dbtype($dsn); } - + if (isset($params->name)) { $this->conn_name = $params->name; } - + // Make things just slightly shorter $this->sql =& $this->db->sql; diff --git a/sys/widgets/connection_sidebar.php b/sys/widgets/connection_sidebar.php index 3391f4b..bd560d1 100644 --- a/sys/widgets/connection_sidebar.php +++ b/sys/widgets/connection_sidebar.php @@ -48,17 +48,12 @@ class Connection_Sidebar extends GtkVBox { $this->settings =& Settings::get_instance(); - //$dblabel = new GtkLabel('Database Connections'); - //$dblabel->set_alignment(0,0); - $add_button = new GtkButton(); $add_button->set_label("New Connnection"); $add_button->set_image(GTKImage::new_from_stock(GTK::STOCK_ADD, Gtk::ICON_SIZE_SMALL_TOOLBAR)); $add_button->connect_simple('clicked', array($this, 'new_conn')); - //$this->pack_start($dblabel, FALSE, FALSE); - // Treeview to show database connections { // Render the treeview @@ -80,6 +75,8 @@ class Connection_Sidebar extends GtkVBox { /** * Renders the connection sidebar widget + * + * @return void */ protected function _render() { @@ -138,6 +135,7 @@ class Connection_Sidebar extends GtkVBox { * @param GtkCellRenderer $cell * @param GtkTreeModel $this->model * @param GtkTreeIter $iter + * @return void */ public function set_icon($col, $cell, $model, $iter) { @@ -167,6 +165,7 @@ class Connection_Sidebar extends GtkVBox { * @param GtkCellRenderer $cell * @param GtkTreeModel $this->model * @param GtkTreeIter $iter + * @return void */ public function set_label($col, $cell, $model, $iter) { @@ -184,6 +183,7 @@ class Connection_Sidebar extends GtkVBox { * @param GtkCellRenderer $cell * @param GtkTreeModel $model * @param GtkTreeIter $iter + * @return void */ public function set_status_icon($col, $cell, $model, $iter) { @@ -311,6 +311,8 @@ class Connection_Sidebar extends GtkVBox { /** * Recreate sidebar widget to update connections + * + * @return void */ public function refresh() { @@ -322,6 +324,8 @@ class Connection_Sidebar extends GtkVBox { /** * Update the connection information for an existing connection + * + * @return void */ public function edit_connection() { @@ -382,13 +386,15 @@ class Connection_Sidebar extends GtkVBox { /** * Disconnect from a database + * + * @return void */ public function db_disconnect() { $data = $this->treeview->get(0); DB_Reg::remove_db($data->name); - DB_Tabs::reset(); + DB_Tabs::reset($data->name); $this->refresh(); } @@ -399,6 +405,7 @@ class Connection_Sidebar extends GtkVBox { * Change tabs based on db connection selected * * @param type $view + * @return void */ public function switch_tab($view) { diff --git a/sys/widgets/data_grid.php b/sys/widgets/data_grid.php index 8290ab1..137dd45 100644 --- a/sys/widgets/data_grid.php +++ b/sys/widgets/data_grid.php @@ -67,7 +67,9 @@ class Data_Grid extends GtkTreeView { // -------------------------------------------------------------------------- /** - * Empty the model + * Clear datagrid + * + * @return void */ public function reset() { @@ -112,9 +114,10 @@ class Data_Grid extends GtkTreeView { * Create a datagrid from the provided data array * * @param array $data + * @param array $events * @return void */ - public function render_data($data) + public function render_data($data, $events=array()) { if ( ! is_array($data)) { diff --git a/sys/widgets/db_info_widget.php b/sys/widgets/db_info_widget.php index 117eab1..668eff2 100644 --- a/sys/widgets/db_info_widget.php +++ b/sys/widgets/db_info_widget.php @@ -102,7 +102,7 @@ class DB_Info_Widget extends GtkTable { $this->port->set_text($db->port); // Layout the table - $this->layout(); + $this->_layout(); // Select the proper db type if editing if ( ! empty($db->type)) @@ -136,104 +136,6 @@ class DB_Info_Widget extends GtkTable { // -------------------------------------------------------------------------- - /** - * Table layout - */ - public function layout() - { - // Reset defaults when changing db types - $this->dbtype->connect_simple("changed", array($this, "change_db")); - - //Table attach - //$tbl->attach(left_start, right_stop, top_start, bottom_stop) - - // Placeholder vars for y values, so that rows can be - // easily moved - $y1 = -1; - $y2 = 0; - - // Connection name - { - $this->_add_row("Connection name", 'conn', $y1, $y2); - } - - // Database type - { - $dbtypelbl = new GtkLabel("Database Type"); - $typealign = new GtkAlignment(0, 0.5, 0, 0); - $typealign->add($dbtypelbl); - $this->attach($typealign, 0, 1, ++$y1, ++$y2); - $this->attach($this->dbtype, 1, 2, $y1, $y2); - } - - // DB File - { - $this->_add_row("Database File", 'db_file', $y1, $y2); - } - - // First Db - { - $this->_add_row("Database Name", 'conn_db', $y1, $y2); - } - - // Host - { - $this->_add_row("Host", 'host', $y1, $y2); - } - - // Port - { - $this->_add_row("Port", 'port', $y1, $y2); - } - - // Username - { - $this->_add_row("User", 'user', $y1, $y2); - } - - // Password - { - $this->_add_row("Password", 'pass', $y1, $y2); - } - - // Add/Edit connection button - { - $conn_name = $this->conn->get_text(); - $caption = (empty($conn_name)) ? 'Add Connection' : 'Update Connection'; - - $add_button = new GtkButton(); - $add_button->set_label($caption); - - ( ! empty($conn_name)) - ? $add_button->set_image(GTKImage::new_from_stock(GTK::STOCK_SAVE, - GTK::ICON_SIZE_SMALL_TOOLBAR)) - : $add_button->set_image(GTKImage::new_from_stock(GTK::STOCK_ADD, - Gtk::ICON_SIZE_SMALL_TOOLBAR)); - - $this->attach($add_button, 0, 1, ++$y1, ++$y2); - - if ( ! empty($conn_name)) - { - $add_button->connect_simple("clicked", array($this, 'db_edit')); - } - else - { - $add_button->connect_simple("clicked", array($this, 'db_add')); - } - - } - - // Test connection button - { - $test_button = new GtkButton(); - $test_button->set_label("Test Connection"); - $this->attach($test_button, 1, 2, $y1, $y2); - $test_button->connect_simple("clicked", array($this, 'test_conn')); - } - } - - // -------------------------------------------------------------------------- - /** * Set defaults for new database type * @@ -350,6 +252,8 @@ class DB_Info_Widget extends GtkTable { /** * Adds the database to the settings file + * + * @return void */ public function db_add() { @@ -383,6 +287,8 @@ class DB_Info_Widget extends GtkTable { /** * Edit an existing database connection + * + * @return void */ public function db_edit() { @@ -419,6 +325,8 @@ class DB_Info_Widget extends GtkTable { /** * Test a db connection, and display a popup with the result of the test + * + * @return void */ public function test_conn() { @@ -524,6 +432,7 @@ class DB_Info_Widget extends GtkTable { * @param string $vname * @param int &$y1 * @param int &$y2 + * @return void */ private function _add_row($label, $vname, &$y1, &$y2) { @@ -538,5 +447,105 @@ class DB_Info_Widget extends GtkTable { $this->attach($lblalign, 0, 1, ++$y1, ++$y2); $this->attach($vname, 1, 2, $y1, $y2); } + + // -------------------------------------------------------------------------- + + /** + * Table layout + * + * @return void + */ + private function _layout() + { + // Reset defaults when changing db types + $this->dbtype->connect_simple("changed", array($this, "change_db")); + + //Table attach + //$tbl->attach(left_start, right_stop, top_start, bottom_stop) + + // Placeholder vars for y values, so that rows can be + // easily moved + $y1 = -1; + $y2 = 0; + + // Connection name + { + $this->_add_row("Connection name", 'conn', $y1, $y2); + } + + // Database type + { + $dbtypelbl = new GtkLabel("Database Type"); + $typealign = new GtkAlignment(0, 0.5, 0, 0); + $typealign->add($dbtypelbl); + $this->attach($typealign, 0, 1, ++$y1, ++$y2); + $this->attach($this->dbtype, 1, 2, $y1, $y2); + } + + // DB File + { + $this->_add_row("Database File", 'db_file', $y1, $y2); + } + + // First Db + { + $this->_add_row("Database Name", 'conn_db', $y1, $y2); + } + + // Host + { + $this->_add_row("Host", 'host', $y1, $y2); + } + + // Port + { + $this->_add_row("Port", 'port', $y1, $y2); + } + + // Username + { + $this->_add_row("User", 'user', $y1, $y2); + } + + // Password + { + $this->_add_row("Password", 'pass', $y1, $y2); + } + + // Add/Edit connection button + { + $conn_name = $this->conn->get_text(); + $caption = (empty($conn_name)) ? 'Add Connection' : 'Update Connection'; + + $add_button = new GtkButton(); + $add_button->set_label($caption); + + ( ! empty($conn_name)) + ? $add_button->set_image(GTKImage::new_from_stock(GTK::STOCK_SAVE, + GTK::ICON_SIZE_SMALL_TOOLBAR)) + : $add_button->set_image(GTKImage::new_from_stock(GTK::STOCK_ADD, + Gtk::ICON_SIZE_SMALL_TOOLBAR)); + + $this->attach($add_button, 0, 1, ++$y1, ++$y2); + + if ( ! empty($conn_name)) + { + $add_button->connect_simple("clicked", array($this, 'db_edit')); + } + else + { + $add_button->connect_simple("clicked", array($this, 'db_add')); + } + + } + + // Test connection button + { + $test_button = new GtkButton(); + $test_button->set_label("Test Connection"); + $this->attach($test_button, 1, 2, $y1, $y2); + $test_button->connect_simple("clicked", array($this, 'test_conn')); + } + } } // End of db_info_widget.php \ No newline at end of file diff --git a/sys/widgets/db_tabs.php b/sys/widgets/db_tabs.php index c9b1d61..8ea9cbd 100644 --- a/sys/widgets/db_tabs.php +++ b/sys/widgets/db_tabs.php @@ -71,6 +71,27 @@ class DB_tabs extends GTKNotebook { // -------------------------------------------------------------------------- + /** + * Create popup window with table data + * + * @param GTKTreeView $view + * @param array $path + * @param GtkTreeviewColumn $col + * @param Query_Builder $conn + * @return void + */ + public function show_table_data($view, $path, $col, &$conn) + { + $table = $view->get(0); + + $query = $conn->get($table); + $data = $query->fetchAll(PDO::FETCH_ASSOC); + + return new DB_Table_data($data); + } + + // -------------------------------------------------------------------------- + /** * Create tabs for database aspects * @@ -85,9 +106,9 @@ class DB_tabs extends GTKNotebook { self::$instance->hide_all(); // 'Databases' Tab - { + /*{ self::_add_tab($conn, 'Databases', 'Db Name', 'get_dbs'); - } + }*/ // 'Schemas' Tab { @@ -106,9 +127,15 @@ class DB_tabs extends GTKNotebook { } // 'System Tables' Tab - { - self::_add_tab($conn, 'System Tables', 'Table Name', 'get_system_tables'); - } + /*{ + self::_add_tab($conn, 'System Tables', 'Table Name', 'get_system_tables', array( + array( + 'row-activated', + array(self::$instance, 'show_table_data'), + $conn + ) + )); + }*/ // 'Views' Tab { @@ -150,8 +177,11 @@ class DB_tabs extends GTKNotebook { /** * Remove current tabs + * + * @param string $conn_name + * @return void */ - public static function reset() + public static function reset($conn_name = '') { self::$instance->hide_all(); @@ -160,6 +190,11 @@ class DB_tabs extends GTKNotebook { self::$instance->remove_page($i); } + if ( ! empty($conn_name)) + { + unset(self::$instance->data->{$conn_name}); + } + self::$instance->show_all(); } @@ -182,18 +217,13 @@ class DB_tabs extends GTKNotebook { $conn_name = $conn->conn_name; - if ( ! isset(self::$instance->data->{$conn_name})) - { - self::$instance->data->{$conn_name}= array(); - } + $instance_data = self::$instance->_get_db_info($conn_name, $tab_name); - $instance_data =& self::$instance->data->{$conn_name}; - - $tab_data = (empty($instance_data[$tab_name])) + $tab_data = ($instance_data === FALSE) ? call_user_func_array(array($conn, $method), array()) - : $instance_data[$tab_name]; + : $instance_data; - $instance_data[$tab_name] = $tab_data; + self::$instance->_set_db_info($conn_name, $tab_name, $tab_data); if ($tab_data !== FALSE) { @@ -236,18 +266,13 @@ class DB_tabs extends GTKNotebook { $conn_name = $conn->conn_name; - if ( ! isset(self::$instance->data->{$conn_name})) - { - self::$instance->data->{$conn_name}= array(); - } + $instance_data = self::$instance->_get_db_info($conn_name, $tab_name); - $instance_data =& self::$instance->data->{$conn_name}; - - $tab_data = (empty($instance_data[$tab_name])) + $tab_data = ($instance_data === FALSE) ? call_user_func_array(array($conn, $method), array()) - : $instance_data[$tab_name]; + : $instance_data; - $instance_data[$tab_name] = $tab_data; + self::$instance->_set_db_info($conn_name, $tab_name, $tab_data); if ( ! empty($tab_data)) { @@ -263,22 +288,42 @@ class DB_tabs extends GTKNotebook { // -------------------------------------------------------------------------- /** - * Create popup window with table data + * Returns cached database data for the tab and connection specified * - * @param GTKTreeView $view - * @param array $path - * @param GtkTreeviewColumn $col - * @param Query_Builder $conn - * @return void + * @param type $conn_name + * @param type $tab_name + * @return mixed */ - public function show_table_data($view, $path, $col, &$conn) + private function _get_db_info($conn_name, $tab_name) { - $table = $view->get(0); + $data =& self::$instance->data; - $query = $conn->get($table); - $data = $query->fetchAll(PDO::FETCH_ASSOC); + if ( ! isset($data->{$conn_name})) + { + $data->{$conn_name}= array(); + return FALSE; + } - return new DB_Table_data($data); + if ( ! isset($data->{$conn_name}[$tab_name])) + { + return FALSE; + } + + return $data->{$conn_name}[$tab_name]; + } + + // -------------------------------------------------------------------------- + + /** + * Sets cached database data for the tab and connection specified + * + * @param type $conn_name + * @param type $tab_name + * @param type $data + */ + private function _set_db_info($conn_name, $tab_name, $data) + { + self::$instance->data->{$conn_name}[$tab_name] = $data; } } // End of db_tabs.php diff --git a/sys/windows/db_table_data.php b/sys/windows/db_table_data.php index e0a7f3d..9e24b24 100644 --- a/sys/windows/db_table_data.php +++ b/sys/windows/db_table_data.php @@ -23,37 +23,26 @@ class DB_Table_Data extends GTKWindow { { parent::__construct(); - $this->set_title("Table Data"); $this->set_position(Gtk::WIN_POS_CENTER_ALWAYS); $this->set_destroy_with_parent(TRUE); + + // Add the scrolled window $this->win = new GTKScrolledWindow(); $this->win->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $this->add($this->win); - $this->_render($data); - // Resize to a sane size - $this->set_size_request(640, 480); - - } - - /** - * Layout the window - * - * @param array $data - * @return void - */ - protected function _render($data) - { + // Layout the widgets $view = new Data_Grid(); $view->render_data($data); // Add the grid to the window $this->win->add_with_viewport($view); + // Show everything $this->show_all(); } } diff --git a/sys/windows/main.php b/sys/windows/main.php index 9ec9be1..d54b590 100644 --- a/sys/windows/main.php +++ b/sys/windows/main.php @@ -59,6 +59,8 @@ class Main extends GtkWindow { /** * Some cleanup for when the main window is closed + * + * @return void */ public function __destruct() { @@ -78,7 +80,9 @@ class Main extends GtkWindow { // -------------------------------------------------------------------------- /** - * Quits the GTK loop + * Exits the GTK loop + * + * @return void */ public function quit() {