diff --git a/data/assets/screenshots/sequeler-screenshot3.png b/data/assets/screenshots/sequeler-screenshot3.png index 5aa27d85..12cdda74 100644 Binary files a/data/assets/screenshots/sequeler-screenshot3.png and b/data/assets/screenshots/sequeler-screenshot3.png differ diff --git a/data/assets/screenshots/sequeler-screenshot4.png b/data/assets/screenshots/sequeler-screenshot4.png new file mode 100644 index 00000000..e6115399 Binary files /dev/null and b/data/assets/screenshots/sequeler-screenshot4.png differ diff --git a/data/com.github.alecaddd.sequeler.appdata.xml.in.in b/data/com.github.alecaddd.sequeler.appdata.xml.in.in index e80066b6..5c5a9f45 100644 --- a/data/com.github.alecaddd.sequeler.appdata.xml.in.in +++ b/data/com.github.alecaddd.sequeler.appdata.xml.in.in @@ -37,6 +37,18 @@ @appid@ + + +

Query Tab Bonanza!

+
    +
  • Fix ORDER BY in PostgreSQL Relationship view.
  • +
  • Improve MySQL structure view.
  • +
  • Drop Granite.Settings in favor of GLib.Settings.
  • +
  • Implement Granite.Notebook on the Query tab.
  • +
  • Show query error messages inline.
  • +
+
+

New features and improvements

@@ -418,6 +430,9 @@ https://raw.githubusercontent.com/Alecaddd/sequeler/master/data/assets/screenshots/sequeler-screenshot3.png + + https://raw.githubusercontent.com/Alecaddd/sequeler/master/data/assets/screenshots/sequeler-screenshot4.png + Alessandro Castellani @appid@.desktop diff --git a/data/stylesheet.css b/data/stylesheet.css index d7bf5ec4..6279751f 100644 --- a/data/stylesheet.css +++ b/data/stylesheet.css @@ -115,3 +115,13 @@ infobar.inline revealer > box { background: #fff; color: #000; } + +.query-error { + background-color: alpha (@STRAWBERRY_300, 0.2); + border: 1px solid @STRAWBERRY_500; + border-radius: 4px; +} + +button.notebook-temp-fix image { + color: @selected_fg_color; +} diff --git a/debian/changelog b/debian/changelog index 0d34c7c4..964a4e6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +com.github.alecaddd.sequeler (0.7.6) xenial; urgency=medium + + * Fix ORDER BY in PostgreSQL Relationship view. + * Improve MySQL structure view. + * Drop Granite.Settings in favor of GLib.Settings. + * Implement Granite.Notebook on the Query tab. + * Show query error messages inline. + + -- Alessandro Castellani Thu, 09 Apr 2020 11:00:00 -0700 + com.github.alecaddd.sequeler (0.7.5) xenial; urgency=medium * You can now duplicate connections. @@ -5,7 +15,7 @@ com.github.alecaddd.sequeler (0.7.5) xenial; urgency=medium * Quickly jump to a specific result page with the handy dandy pagination popover. * Show Comment Column inside table structure view. - -- Alessandro Castellani Thu, 04 Apr 2020 11:00:00 -0700 + -- Alessandro Castellani Sat, 04 Apr 2020 11:00:00 -0700 com.github.alecaddd.sequeler (0.7.4) xenial; urgency=medium diff --git a/meson.build b/meson.build index 524c7cb8..5fa44ede 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ # project name and programming language project('com.github.alecaddd.sequeler', 'vala', 'c', - version: '0.7.5') + version: '0.7.6') cc = meson.get_compiler('c') m_dep = cc.find_library('m', required: true) diff --git a/src/Layouts/DataBaseView.vala b/src/Layouts/DataBaseView.vala index bb002edc..b3ab36a5 100644 --- a/src/Layouts/DataBaseView.vala +++ b/src/Layouts/DataBaseView.vala @@ -27,7 +27,9 @@ public class Sequeler.Layouts.DataBaseView : Gtk.Grid { public Sequeler.Layouts.Views.Structure structure; public Sequeler.Layouts.Views.Content content; public Sequeler.Layouts.Views.Relations relations; - public Sequeler.Layouts.Views.Query query; + public Granite.Widgets.DynamicNotebook query; + + private Sequeler.Layouts.Views.Query tab_to_restore; public Gtk.MenuButton font_style; @@ -98,7 +100,9 @@ public class Sequeler.Layouts.DataBaseView : Gtk.Grid { zoom_out_button.action_name = Sequeler.Services.ActionManager.ACTION_PREFIX + Sequeler.Services.ActionManager.ACTION_ZOOM_OUT; zoom_out_button.tooltip_markup = Granite.markup_accel_tooltip ({"minus"}, _("Zoom Out")); - var zoom_default_button = new Gtk.Button.with_label ("100%"); + var zoom_default_button = new Gtk.Button.with_label ( + "%.0f%%".printf (window.action_manager.get_current_font_size () * 10) + ); zoom_default_button.action_name = Sequeler.Services.ActionManager.ACTION_PREFIX + Sequeler.Services.ActionManager.ACTION_ZOOM_DEFAULT; zoom_default_button.tooltip_markup = Granite.markup_accel_tooltip ({"0"}, _("Zoom 1:1")); @@ -164,17 +168,13 @@ public class Sequeler.Layouts.DataBaseView : Gtk.Grid { view_options.add (font_style); - // Content View buttons - // Structure View buttons - // Relations View buttons - toolbar.attach (view_options, 1, 0, 1, 1); stack = new Gtk.Stack (); structure = new Sequeler.Layouts.Views.Structure (window); content = new Sequeler.Layouts.Views.Content (window); relations = new Sequeler.Layouts.Views.Relations (window); - query = new Sequeler.Layouts.Views.Query (window); + query = get_query_notebook (); stack.add_named (structure, "Structure"); stack.add_named (content, "Content"); @@ -203,17 +203,71 @@ public class Sequeler.Layouts.DataBaseView : Gtk.Grid { color_button_dark.clicked.connect (() => { Sequeler.settings.style_scheme = "solarized-dark"; - query.update_color_style (); + (query.current.page as Layouts.Views.Query).update_color_style (); }); color_button_light.clicked.connect (() => { Sequeler.settings.style_scheme = "solarized-light"; - query.update_color_style (); + (query.current.page as Layouts.Views.Query).update_color_style (); }); color_button_white.clicked.connect (() => { Sequeler.settings.style_scheme = "classic"; - query.update_color_style (); + (query.current.page as Layouts.Views.Query).update_color_style (); + }); + } + + private Granite.Widgets.DynamicNotebook get_query_notebook () { + var notebook = new Granite.Widgets.DynamicNotebook (); + notebook.add_button_tooltip = _("Create a new Query Tab"); + notebook.expand = true; + notebook.allow_restoring = true; + notebook.max_restorable_tabs = 1; + + var first_page = new Sequeler.Layouts.Views.Query (window); + var first_tab = new Granite.Widgets.Tab ( + _("Query"), new ThemedIcon ("user-offline"), first_page + ); + first_page.update_tab_indicator.connect ((status) => { + var icon = status ? new ThemedIcon ("user-available") : new ThemedIcon ("dialog-error"); + first_tab.icon = icon; }); + notebook.insert_tab (first_tab, 0); + + notebook.new_tab_requested.connect (() => { + var new_page = new Sequeler.Layouts.Views.Query (window); + var new_tab = new Granite.Widgets.Tab ( + _("Query %i").printf (notebook.n_tabs), new ThemedIcon ("user-offline"), new_page + ); + new_page.update_tab_indicator.connect ((status) => { + var icon = status ? new ThemedIcon ("user-available") : new ThemedIcon ("dialog-error"); + new_tab.icon = icon; + }); + notebook.insert_tab (new_tab, notebook.n_tabs - 1); + }); + + notebook.close_tab_requested.connect ((tab) => { + if (notebook.n_tabs == 1) { + var new_page = new Sequeler.Layouts.Views.Query (window); + var new_tab = new Granite.Widgets.Tab ( + _("Query"), new ThemedIcon ("user-offline"), new_page + ); + notebook.insert_tab (new_tab, notebook.n_tabs - 1); + } + tab_to_restore = tab.page as Sequeler.Layouts.Views.Query; + tab.restore_data = tab.label; + return true; + }); + + notebook.tab_restored.connect ((label, data, icon) => { + var tab = new Granite.Widgets.Tab (label, icon, tab_to_restore); + tab_to_restore.update_tab_indicator.connect ((status) => { + var update_icon = status ? new ThemedIcon ("user-available") : new ThemedIcon ("dialog-error"); + tab.icon = update_icon; + }); + notebook.insert_tab (tab, notebook.n_tabs - 1); + }); + + return notebook; } } diff --git a/src/Layouts/Views/Query.vala b/src/Layouts/Views/Query.vala index acbbfea2..2463ea5f 100644 --- a/src/Layouts/Views/Query.vala +++ b/src/Layouts/Views/Query.vala @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 Alecaddd (http://alecaddd.com) + * Copyright (c) 2017-2020 Alecaddd (https://alecaddd.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public @@ -27,6 +27,8 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { public Gtk.SourceBuffer buffer_copy; public Gtk.SourceStyleSchemeManager style_scheme_manager; public Gtk.CssProvider style_provider; + private Gtk.Revealer error_revealer; + private Gtk.Label error_message; public Gtk.ScrolledWindow scroll_results; public Gtk.Spinner spinner; public Gtk.Label loading_msg; @@ -44,6 +46,8 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { public Gtk.Paned panels; public Sequeler.Partials.TreeBuilder result_data; + public signal void update_tab_indicator (bool status); + public Query (Sequeler.Window main_window) { Object ( orientation: Gtk.Orientation.VERTICAL, @@ -243,14 +247,30 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { scroll_results.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); scroll_results.expand = true; + error_revealer = new Gtk.Revealer (); + + var error_grid = new Gtk.Grid (); + error_grid.get_style_context ().add_class ("query-error"); + error_grid.hexpand = true; + error_grid.margin = 6; + + error_message = new Gtk.Label (""); + error_message.wrap = true; + error_message.margin = 6; + error_grid.add (error_message); + + error_revealer.add (error_grid); + error_revealer.reveal_child = false; + var info_bar = new Gtk.Grid (); info_bar.get_style_context ().add_class ("library-toolbar"); info_bar.attach (build_results_msg (), 0, 0, 1, 1); info_bar.attach (build_export_btn (), 1, 0, 1, 1); results_view.attach (action_bar, 0, 0, 1, 1); - results_view.attach (scroll_results, 0, 1, 1, 1); - results_view.attach (info_bar, 0, 2, 1, 1); + results_view.attach (error_revealer, 0, 1, 1, 1); + results_view.attach (scroll_results, 0, 2, 1, 1); + results_view.attach (info_bar, 0, 3, 1, 1); return results_view; } @@ -272,11 +292,12 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { } public Gtk.Button build_run_button () { - var run_image = new Gtk.Image.from_icon_name ("system-run-symbolic", Gtk.IconSize.BUTTON); run_button = new Gtk.Button.with_label (_("Run Query")); run_button.get_style_context ().add_class ("suggested-action"); + run_button.get_style_context ().add_class ("notebook-temp-fix"); run_button.always_show_image = true; - run_button.set_image (run_image); + run_button.image = new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.BUTTON); + run_button.image.valign = Gtk.Align.CENTER; run_button.can_focus = false; run_button.margin = 10; run_button.sensitive = false; @@ -290,18 +311,18 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { var result_box = new Gtk.Grid (); icon_success = new Gtk.Image.from_icon_name ("process-completed-symbolic", Gtk.IconSize.BUTTON); - icon_success.margin_start = 7; + icon_success.margin_start = 6; icon_success.visible = false; icon_success.no_show_all = true; icon_fail = new Gtk.Image.from_icon_name ("dialog-error-symbolic", Gtk.IconSize.BUTTON); - icon_fail.margin_start = 7; + icon_fail.margin_start = 6; icon_fail.visible = false; icon_fail.no_show_all = true; result_message = new Gtk.Label (_("No Results Available")); result_message.halign = Gtk.Align.START; - result_message.margin = 7; + result_message.margin = 6; result_message.margin_top = 6; result_message.hexpand = true; result_message.wrap = true; @@ -314,6 +335,7 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { } public void show_result_icon (bool status) { + update_tab_indicator (status); if (status) { icon_success.visible = true; icon_success.no_show_all = false; @@ -393,18 +415,21 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { } } - private async Gda.DataModel? select_statement (string query) { - return yield window.main.connection_manager.init_select_query (query); + private async Gee.HashMap select_statement (string query) { + return yield window.main.connection_manager.init_silent_select_query (query); } - public async int? non_select_statement (string query) { - return yield window.main.connection_manager.init_query (query); + public async Gee.HashMap non_select_statement (string query) { + return yield window.main.connection_manager.init_silent_query (query); } - public void handle_select_response (Gda.DataModel? response) { - response_data = response; + public void handle_select_response (Gee.HashMap response) { + foreach (var entry in response.entries) { + response_data = entry.key; + on_query_error (entry.value); + } - if (response == null) { + if (response_data == null) { toggle_loading_msg (false); spinner.stop (); @@ -415,30 +440,36 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { return; } + if (error_revealer.get_reveal_child ()) { + error_revealer.reveal_child = false; + } + if (result_data != null) { scroll_results.remove (result_data); result_data = null; } - result_data = new Sequeler.Partials.TreeBuilder (response, window); + result_data = new Sequeler.Partials.TreeBuilder (response_data, window); toggle_loading_msg (false); spinner.stop (); - result_message.label = _("%d Total Results").printf (response.get_n_rows ()); + result_message.label = _("%d Total Results").printf (response_data.get_n_rows ()); show_result_icon (true); scroll_results.add (result_data); scroll_results.show_all (); - if (response.get_n_rows () == 0) { - export_button.sensitive = false; - } else { - export_button.sensitive = true; - } + export_button.sensitive = response_data.get_n_rows () == 0 ? false : true; } - public void handle_query_response (int? response) { + public void handle_query_response (Gee.HashMap data) { + string? response = null; + foreach (var entry in data.entries) { + response = entry.key; + on_query_error (entry.value); + } + toggle_loading_msg (false); spinner.stop (); @@ -453,8 +484,12 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { return; } - if (response > 0) { - result_message.label = _("Query Successfully Executed! Rows Affected: %d").printf (response); + if (error_revealer.get_reveal_child ()) { + error_revealer.reveal_child = false; + } + + if (int.parse (response) > 0) { + result_message.label = _("Query Successfully Executed! Rows Affected: %s").printf (response); show_result_icon (true); } else { result_message.label = _("Query Executed!"); @@ -469,6 +504,20 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { window.main.database_view.structure.reset.begin (); } + private void on_query_error (string error) { + if (error == "") { + return; + } + + if (result_data != null) { + scroll_results.remove (result_data); + result_data = null; + } + + error_message.label = error; + error_revealer.reveal_child = true; + } + private bool is_semicolon (unichar semicolon) { return semicolon.to_string () == ";"; } @@ -490,8 +539,6 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { file = save_dialog.get_file (); save_to_file (type); break; - default: - break; } dialog.destroy (); }); @@ -508,24 +555,21 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { separator_holder.id = "SEPARATOR"; try { separator_holder.set_value (","); - } - catch (GLib.Error err) { + } catch (GLib.Error err) { window.main.connection_manager.query_warning (err.message); } first_line_holder.id = "NAMES_ON_FIRST_LINE"; try { first_line_holder.set_value (true); - } - catch (GLib.Error err) { + } catch (GLib.Error err) { window.main.connection_manager.query_warning (err.message); } overwrite_holder.id = "OVERWRITE"; try { overwrite_holder.set_value (true); - } - catch (GLib.Error err) { + } catch (GLib.Error err) { window.main.connection_manager.query_warning (err.message); } @@ -544,7 +588,7 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { catch (GLib.Error err) { window.main.connection_manager.query_warning (err.message); } - break; + break; case 2: // Export as plain text try { @@ -553,9 +597,7 @@ public class Sequeler.Layouts.Views.Query : Gtk.Grid { catch (GLib.Error err) { window.main.connection_manager.query_warning (err.message); } - break; - default: - break; + break; } } } diff --git a/src/Services/ActionManager.vala b/src/Services/ActionManager.vala index 68d9b3fc..066b18fb 100644 --- a/src/Services/ActionManager.vala +++ b/src/Services/ActionManager.vala @@ -99,8 +99,10 @@ public class Sequeler.Services.ActionManager : Object { window.main.database_schema.scroll.remove (window.main.database_schema.scroll.get_child ()); } - window.main.database_view.query.buffer.text = ""; - window.main.database_view.query.export_button.sensitive = false; + if (window.main.database_view.query.n_tabs > 0) { + (window.main.database_view.query.current.page as Layouts.Views.Query).buffer.text = ""; + (window.main.database_view.query.current.page as Layouts.Views.Query).export_button.sensitive = false; + } window.main.database_view.structure.reset.begin (); window.main.database_view.structure.table_name = ""; @@ -143,13 +145,13 @@ public class Sequeler.Services.ActionManager : Object { return; } - var query = window.main.database_view.query.get_text ().strip (); + var query = (window.main.database_view.query.current.page as Layouts.Views.Query).get_text ().strip (); if (query == "") { return; } - window.main.database_view.query.run_query (query); + (window.main.database_view.query.current.page as Layouts.Views.Query).run_query (query); } public static void action_from_group (string action_name, ActionGroup? action_group) { @@ -158,7 +160,7 @@ public class Sequeler.Services.ActionManager : Object { public void set_default_zoom () { Sequeler.settings.font = get_current_font () + " " + get_default_font_size ().to_string (); - window.main.database_view.query.update_font_style (); + (window.main.database_view.query.current.page as Layouts.Views.Query).update_font_style (); } // Ctrl + scroll @@ -194,7 +196,7 @@ public class Sequeler.Services.ActionManager : Object { string new_font = font + " " + font_size.to_string (); Sequeler.settings.font = new_font; - window.main.database_view.query.update_font_style (); + (window.main.database_view.query.current.page as Layouts.Views.Query).update_font_style (); } public string get_current_font () { @@ -210,13 +212,13 @@ public class Sequeler.Services.ActionManager : Object { } public string get_default_font () { - string font = window.main.database_view.query.default_font; + string font = (window.main.database_view.query.current.page as Layouts.Views.Query).default_font; string font_family = font.substring (0, font.last_index_of (" ")); return font_family; } public double get_default_font_size () { - string font = window.main.database_view.query.default_font; + string font = (window.main.database_view.query.current.page as Layouts.Views.Query).default_font; string font_size = font.substring (font.last_index_of (" ") + 1); return double.parse (font_size); } diff --git a/src/Services/ConnectionManager.vala b/src/Services/ConnectionManager.vala index 8b977c6f..059a09c3 100644 --- a/src/Services/ConnectionManager.vala +++ b/src/Services/ConnectionManager.vala @@ -25,6 +25,7 @@ public class Sequeler.Services.ConnectionManager : Object { private Object _db_type; public signal void ssh_tunnel_ready (); + public signal void query_error (string error); public Object db_type { get { return _db_type; } @@ -437,6 +438,11 @@ public class Sequeler.Services.ConnectionManager : Object { return connection.execute_non_select_command (query); } + public async string run_silent_query (string query) throws Error requires (connection.is_opened ()) { + var result = connection.execute_non_select_command (query); + return result.to_string (); + } + public Gda.DataModel? run_select (string query) throws Error { return connection.execute_select_command (query); } @@ -496,6 +502,29 @@ public class Sequeler.Services.ConnectionManager : Object { return result; } + public async Gee.HashMap init_silent_select_query (string query) { + var result = new Gee.HashMap (); + Gda.DataModel? data = null; + SourceFunc callback = init_silent_select_query.callback; + var error = ""; + + new Thread (null, () => { + try { + data = run_select (query); + } catch (Error e) { + error = e.message; + data = null; + } + Idle.add ((owned) callback); + return null; + }); + + yield; + + result.@set (data, error); + return result; + } + public async int? init_query (string query) { int result = 0; var error = ""; @@ -514,6 +543,25 @@ public class Sequeler.Services.ConnectionManager : Object { return result; } + public async Gee.HashMap init_silent_query (string query) { + var result = new Gee.HashMap (); + string? data = null; + var error = ""; + + try { + data = yield run_silent_query (query); + } catch (Error e) { + error = e.message; + } + + if (error != "") { + data = null; + } + + result.@set (data, error); + return result; + } + public void query_warning (string message) { var message_dialog = new Granite.MessageDialog.with_image_from_icon_name (_("Error!"), message, "dialog-error", Gtk.ButtonsType.NONE); message_dialog.transient_for = window; diff --git a/src/Services/Settings.vala b/src/Services/Settings.vala index 1724c25e..cb2e5d2c 100644 --- a/src/Services/Settings.vala +++ b/src/Services/Settings.vala @@ -19,25 +19,70 @@ * Authored by: Alessandro "Alecaddd" Castellani */ -public class Sequeler.Services.Settings : Granite.Services.Settings { - public int pos_x { get; set; } - public int pos_y { get; set; } - public int window_width { get; set; } - public int window_height { get; set; } - public int sidebar_width { get; set; } - public string[] saved_connections { get; set; } - public int tot_connections { get; set; } - public int limit_results { get; set; } - public bool dark_theme { get; set; } - public bool save_quick { get; set; } - public string version { get; set; } - public bool use_system_font { get; set; } - public string font { get; set; } - public string style_scheme { get; set; } - public int query_area { get; set; } +public class Sequeler.Services.Settings : GLib.Settings { + public int pos_x { + get { return get_int ("pos-x"); } + set { set_int ("pos-x", value); } + } + public int pos_y { + get { return get_int ("pos-y"); } + set { set_int ("pos-y", value); } + } + public int window_width { + get { return get_int ("window-width"); } + set { set_int ("window-width", value); } + } + public int window_height { + get { return get_int ("window-height"); } + set { set_int ("window-height", value); } + } + public int sidebar_width { + get { return get_int ("sidebar-width"); } + set { set_int ("sidebar-width", value); } + } + public string[] saved_connections { + owned get { return get_strv ("saved-connections"); } + set { set_strv ("saved-connections", value); } + } + public int tot_connections { + get { return get_int ("tot-connections"); } + set { set_int ("tot-connections", value); } + } + public int limit_results { + get { return get_int ("limit-results"); } + set { set_int ("limit-results", value); } + } + public bool dark_theme { + get { return get_boolean ("dark-theme"); } + set { set_boolean ("dark-theme", value); } + } + public bool save_quick { + get { return get_boolean ("save-quick"); } + set { set_boolean ("save-quick", value); } + } + public string version { + owned get { return get_string ("version"); } + set { set_string ("version", value); } + } + public bool use_system_font { + get { return get_boolean ("use-system-font"); } + set { set_boolean ("use-system-font", value); } + } + public string font { + owned get { return get_string ("font"); } + set { set_string ("font", value); } + } + public string style_scheme { + owned get { return get_string ("style-scheme"); } + set { set_string ("style-scheme", value); } + } + public int query_area { + get { return get_int ("query-area"); } + set { set_int ("query-area", value); } + } public Settings () { - base (Constants.PROJECT_NAME); + Object (schema_id: Constants.PROJECT_NAME); } public void add_connection (Gee.HashMap data) { diff --git a/src/Services/Types/MySQL.vala b/src/Services/Types/MySQL.vala index c7ecc574..74ce8302 100644 --- a/src/Services/Types/MySQL.vala +++ b/src/Services/Types/MySQL.vala @@ -51,7 +51,7 @@ public class Sequeler.Services.Types.MySQL : Object, DataBaseType { } public string show_table_structure (string table, string? sortby = null, string sort = "ASC") { - var output = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, DATA_TYPE, COLUMN_DEFAULT, COLUMN_KEY, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE table_name = '%s'".printf (table); + var output = "SELECT COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE, COLUMN_KEY, EXTRA, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE table_name = '%s' AND table_schema = DATABASE()".printf (table); if (sortby != null) { output += " ORDER BY %s %s".printf (sortby, sort); diff --git a/src/Services/Types/PostgreSQL.vala b/src/Services/Types/PostgreSQL.vala index f3763ecd..018f27b0 100644 --- a/src/Services/Types/PostgreSQL.vala +++ b/src/Services/Types/PostgreSQL.vala @@ -87,7 +87,7 @@ public class Sequeler.Services.Types.PostgreSQL : Object, DataBaseType { var output = "SELECT ccu.column_name as \"COLUMN_NAME\", tc.constraint_name as \"CONSTRAINT_NAME\", kcu.column_name as \"REFERENCED_COLUMN_NAME\", tc.table_name as \"REFERENCED_TABLE\" FROM information_schema.table_constraints tc JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage ccu ON ccu.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_name='%s' AND ccu.table_schema = '%s'".printf (table, database); if (sortby != null) { - output += " ORDER BY %s %s".printf (sortby, sort); + output += " ORDER BY \"%s\" %s".printf (sortby, sort); } return output; diff --git a/src/Window.vala b/src/Window.vala index 581bd345..5682e872 100644 --- a/src/Window.vala +++ b/src/Window.vala @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2018 Alecaddd (http://alecaddd.com) +* Copyright (c) 2017-2020 Alecaddd (https://alecaddd.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public @@ -8,7 +8,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public @@ -42,9 +42,9 @@ public class Sequeler.Window : Gtk.ApplicationWindow { accel_group = new Gtk.AccelGroup (); add_accel_group (accel_group); + action_manager = new Sequeler.Services.ActionManager (app, this); main = new Sequeler.Layouts.Main (this); headerbar = new Sequeler.Layouts.HeaderBar (this); - action_manager = new Sequeler.Services.ActionManager (app, this); data_manager = new Sequeler.Services.DataManager (); build_ui (); @@ -94,7 +94,11 @@ public class Sequeler.Window : Gtk.ApplicationWindow { settings.window_width = width; settings.window_height = height; settings.sidebar_width = main.get_position (); - settings.query_area = main.database_view.query.panels.get_position (); + if (main.database_view.query.n_tabs > 0) { + settings.query_area = + (main.database_view.query.current.page as Layouts.Views.Query) + .panels.get_position (); + } } public void show_app () {