diff --git a/res/gtk/connection-form.blp b/res/gtk/connection-form.blp
index ca8d56e..7b13b47 100644
--- a/res/gtk/connection-form.blp
+++ b/res/gtk/connection-form.blp
@@ -18,12 +18,12 @@ menu primary_menu {
}
section {
item {
- label: _("_Import Connections");
+ label: _("_Import");
action: "win.import";
}
item {
- label: _("_Export Connections");
+ label: _("_Export");
action: "win.export";
}
}
diff --git a/res/gtk/query-editor.blp b/res/gtk/query-editor.blp
index ae49374..69976f2 100644
--- a/res/gtk/query-editor.blp
+++ b/res/gtk/query-editor.blp
@@ -112,6 +112,10 @@ template $PsequelQueryEditor : Adw.Bin {
spinning: bind template.query-history-viewmodel as <$PsequelQueryHistoryViewModel>.is-loading;
}
+ // Label query_time {
+ // label: bind template.query-history-viewmodel as <$PsequelQueryHistoryViewModel>.query-time;
+ // }
+
Button run_query_btn {
styles ["suggested-action"]
label: "Run Query";
@@ -152,8 +156,9 @@ template $PsequelQueryEditor : Adw.Bin {
hexpand: true;
}
- Label query_time {
- label: bind template.query-history-viewmodel as <$PsequelQueryHistoryViewModel>.query-time;
+ Button export {
+ label: "Export";
+ clicked => $on_export_csv();
}
}
}
diff --git a/res/gtk/schema-main.blp b/res/gtk/schema-main.blp
index a60f096..66b945b 100644
--- a/res/gtk/schema-main.blp
+++ b/res/gtk/schema-main.blp
@@ -86,7 +86,6 @@ template $PsequelSchemaMain : Gtk.Box {
StackPage {
name: "view";
child: $PsequelViewStructureView {
- viewstructure-viewmodel: bind template.view-viewmodel as <$PsequelViewViewModel>.viewstructure-viewmodel;
};
}
};
@@ -106,14 +105,12 @@ template $PsequelSchemaMain : Gtk.Box {
StackPage {
name: "table";
child: $PsequelTableDataView {
- tabledata-viewmodel: bind template.table-viewmodel as <$PsequelTableViewModel>.tabledata-viewmodel;
};
}
StackPage {
name: "view";
child: $PsequelViewDataView {
- viewdata-viewmodel: bind template.view-viewmodel as <$PsequelViewViewModel>.viewdata-viewmodel;
};
}
};
diff --git a/src/application.vala b/src/application.vala
index a33c5f9..370d7f6 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -41,9 +41,6 @@ namespace Psequel {
public int color_scheme { get; set; }
public const int MAX_COLUMNS = 100;
- private PreferencesWindow preference;
-
-
public Application () {
Object (application_id: "me.ppvan.psequel", flags: ApplicationFlags.DEFAULT_FLAGS);
}
@@ -191,14 +188,13 @@ namespace Psequel {
private void on_preferences_action () {
- if (this.preference == null) {
- this.preference = new PreferencesWindow () {
- transient_for = this.active_window,
- modal = true,
- application = this,
- };
- }
- this.preference.present ();
+ var preference = new PreferencesWindow () {
+ transient_for = this.active_window,
+ modal = true,
+ application = this,
+ };
+
+ preference.present ();
}
/**
@@ -225,6 +221,7 @@ namespace Psequel {
var schema_service = new SchemaService (sql_service);
var repository = new ConnectionRepository (Application.settings);
var navigation = new NavigationService ();
+ var export = new ExportService ();
// viewmodels
var conn_vm = new ConnectionViewModel (repository, sql_service, navigation);
@@ -240,6 +237,7 @@ namespace Psequel {
container.register (sql_service);
container.register (schema_service);
+ container.register (export);
container.register (repository);
container.register (navigation);
container.register (conn_vm);
diff --git a/src/meson.build b/src/meson.build
index 83bf305..d34594b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -36,6 +36,7 @@ psequel_sources = [
# 'models/utils.vala',
'services/SQLService.vala',
+ 'services/ExportService.vala',
'services/NavigationService.vala',
'services/ConnectionService.vala',
'services/Container.vala',
diff --git a/src/models/Query.vala b/src/models/Query.vala
index c40b30f..c4dace8 100644
--- a/src/models/Query.vala
+++ b/src/models/Query.vala
@@ -1,28 +1,36 @@
namespace Psequel {
public class Query : Object, Json.Serializable {
- public string sql { get; private set; }
- public Variant[] params;
+
+ // Properties must be public, get, set inorder to Json.Serializable works
+ public string sql { get; set; }
+ public string[] params {get; set;}
public Query (string sql) {
base();
this.sql = sql;
}
- public Query.with_params (string sql, Variant[] params) {
+ public Query.with_params (string sql, string[] params) {
this(sql);
this.params = params;
}
public void set_limit (int limit) {
- if (!is_select ()) {
+ if (!is_dql ()) {
return;
}
sql += @" LIMIT $limit";
}
- private inline bool is_select () {
+ public bool is_dql () {
return sql.up (6) == "SELECT";
}
+ public bool is_ddl () {
+ var regex = /CREATE|DROP|RENAME|ALTER|INSERT|UPDATE|DELETE/;
+ var query = sql.up (6);
+ return regex.match (query, 0, null);
+ }
+
public Query clone () {
return (Query)Json.gobject_deserialize (typeof (Query), Json.gobject_serialize (this));
}
diff --git a/src/models/Schema.vala b/src/models/Schema.vala
index 5e17936..253dd09 100644
--- a/src/models/Schema.vala
+++ b/src/models/Schema.vala
@@ -6,18 +6,10 @@ namespace Psequel {
public class Schema : Object {
public string name { get; private set; }
- public List
tables { get; owned set; }
- public List views {get; owned set;}
-
public Schema (string name) {
Object ();
this.name = name;
}
-
- construct {
- tables = new List ();
- views = new List ();
- }
}
/** Base type for hold info about Table */
diff --git a/src/services/ExportService.vala b/src/services/ExportService.vala
new file mode 100644
index 0000000..0ab2c46
--- /dev/null
+++ b/src/services/ExportService.vala
@@ -0,0 +1,49 @@
+namespace Psequel{
+ public class ExportService : Object {
+
+ public const string DELIMETER = ",";
+ public const string NEWLINE = "\n";
+
+ public ExportService () {
+ }
+
+ // Implement accordding to https://en.wikipedia.org/wiki/Comma-separated_values?useskin=vector#Basic_rules
+ public async void export_csv (File dest, Relation relation) throws PsequelError {
+
+ string[] rows = new string[relation.rows + 1];
+ string[] cols = new string[relation.cols];
+
+ // headers
+ for (int j = 0; j < relation.cols; j++) {
+ cols[j] = quote (relation.get_header (j));
+ }
+ rows[0] = string.joinv (DELIMETER, cols);
+
+ for (int i = 0; i < relation.rows; i++) {
+ cols = new string[relation.cols];
+ var row = relation[i];
+ for (int j = 0; j < relation.cols; j++) {
+ cols[j] = quote (row[j]);
+ }
+
+ rows[i + 1] = string.joinv (DELIMETER, cols);
+ }
+
+ var bytes = new Bytes.take (string.joinv (NEWLINE, rows).data);
+
+ try {
+ yield dest.replace_contents_bytes_async (bytes, null, false, FileCreateFlags.PRIVATE, null, null);
+ } catch (GLib.Error err) {
+ throw new PsequelError.EXPORT_ERROR(err.message);
+ }
+ }
+
+ private string quote (string str) {
+ if (str.contains (DELIMETER)) {
+ return @"\"$(str)\"";
+ }
+
+ return str;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/SQLCompletionProvider.vala b/src/services/SQLCompletionProvider.vala
index f7cca10..bfcdda4 100644
--- a/src/services/SQLCompletionProvider.vala
+++ b/src/services/SQLCompletionProvider.vala
@@ -101,15 +101,15 @@ namespace Psequel {
/*
Query viewmodel is not set until the query view is created.
*/
- yield schema_viewmodel.load_schema (schema_viewmodel.current_schema);
+ // yield schema_viewmodel.load_schema (schema_viewmodel.current_schema);
dynamic_candidates = new List ();
- schema_viewmodel.current_schema.tables.foreach ((table) => {
- dynamic_candidates.append (new Model (table.name, "TABLE"));
- });
+ // schema_viewmodel.current_schema.tables.foreach ((table) => {
+ // dynamic_candidates.append (new Model (table.name, "TABLE"));
+ // });
- schema_viewmodel.current_schema.views.foreach ((view) => {
- dynamic_candidates.append (new Model (view.name, "VIEW"));
- });
+ // schema_viewmodel.current_schema.views.foreach ((view) => {
+ // dynamic_candidates.append (new Model (view.name, "VIEW"));
+ // });
var candidates = new ObservableList ();
candidates.append_all (static_candidates);
diff --git a/src/services/SQLService.vala b/src/services/SQLService.vala
index f3298ee..58a3735 100644
--- a/src/services/SQLService.vala
+++ b/src/services/SQLService.vala
@@ -101,7 +101,7 @@ namespace Psequel {
var status = result.get_status ();
switch (status) {
- case ExecStatus.TUPLES_OK, ExecStatus.COMMAND_OK:
+ case ExecStatus.TUPLES_OK, ExecStatus.COMMAND_OK, ExecStatus.COPY_OUT:
// success
break;
case ExecStatus.FATAL_ERROR:
@@ -145,21 +145,7 @@ namespace Psequel {
}
}
- private async Result exec_query_params_internal (string query, Variant[] params) throws PsequelError {
-
- int n_params = params.length;
- string[] values = new string[n_params];
-
- for (int i = 0; i < n_params; i++) {
- if (params[i].is_of_type (VariantType.STRING)) {
- values[i] = params[i].get_string ();
- } else if (params[i].get_type ().is_basic ()) {
- values[i] = params[i].print (false);
- } else {
- warning ("Programming error, got type '%s'", params[i].get_type_string ());
- assert_not_reached ();
- }
- }
+ private async Result exec_query_params_internal (string query, string[] params) throws PsequelError {
debug ("Exec Param: %s", query);
TimePerf.begin ();
@@ -169,7 +155,7 @@ namespace Psequel {
try {
var worker = new Worker ("exec query params", () => {
- result = active_db.exec_params (query, n_params, null, values, null, null, 0);
+ result = active_db.exec_params (query, params.length, null, params, null, null, 0);
// Jump to yield
Idle.add ((owned) callback);
});
diff --git a/src/services/SchemaService.vala b/src/services/SchemaService.vala
index 9617496..c5b594d 100644
--- a/src/services/SchemaService.vala
+++ b/src/services/SchemaService.vala
@@ -88,93 +88,93 @@ namespace Psequel {
/** Load table list, view list into the schema. */
public async void load_schema (Schema schema) throws PsequelError.QUERY_FAIL {
- yield load_tables_and_views (schema);
+ // yield load_tables_and_views (schema);
}
- private async void load_tables_and_views (Schema schema) {
+ // private async void load_tables_and_views (Schema schema) {
- // old table auto clean by GC
- schema.tables = new List ();
- schema.views = new List ();
+ // // old table auto clean by GC
+ // schema.tables = new List ();
+ // schema.views = new List ();
- var table_groups = new HashTable (GLib.str_hash, GLib.str_equal);
- var view_groups = new HashTable (GLib.str_hash, GLib.str_equal);
+ // var table_groups = new HashTable (GLib.str_hash, GLib.str_equal);
+ // var view_groups = new HashTable (GLib.str_hash, GLib.str_equal);
- var table_names = yield get_tbnames (schema);
+ // var table_names = yield get_tbnames (schema);
- var view_names = yield get_viewnames (schema);
+ // var view_names = yield get_viewnames (schema);
- var columns = yield get_columns (schema);
+ // var columns = yield get_columns (schema);
- var indexes = yield get_indexes (schema);
+ // var indexes = yield get_indexes (schema);
- var fks = yield get_fks (schema);
-
- debug ("cols: %u indx: %u fks: %u", columns.length (), indexes.length (), fks.length ());
-
- table_names.foreach ((tbname) => {
- var table = new Table (schema) {
- name = tbname,
- };
- table_groups.insert (tbname, table);
- });
-
- view_names.foreach ((tbname) => {
- var view = new View (schema) {
- name = tbname,
- };
- view_groups.insert (tbname, view);
- });
-
- columns.foreach ((col) => {
- if (table_groups.contains (col.table)) {
- var table = table_groups.get (col.table);
- table.columns.append (col);
- }
-
- if (view_groups.contains (col.table)) {
- var view = view_groups.get (col.table);
- view.columns.append (col);
- }
- });
-
- indexes.foreach ((index) => {
- if (table_groups.contains (index.table)) {
- var table = table_groups.get (index.table);
- table.indexes.append (index);
- }
-
- if (view_groups.contains (index.table)) {
- var view = view_groups.get (index.table);
- view.indexes.append (index);
- }
- });
-
- fks.foreach ((fk) => {
- if (table_groups.contains (fk.table)) {
- var table = table_groups.get (fk.table);
- table.foreign_keys.append (fk);
- }
- });
-
- var tables = table_groups.steal_all_values ();
-
- for (int i = 0; i < tables.length; i++) {
- schema.tables.append (tables[i]);
- }
-
- var views = view_groups.steal_all_values ();
-
- for (int i = 0; i < views.length; i++) {
- schema.views.append (views[i]);
- }
- }
+ // var fks = yield get_fks (schema);
+
+ // debug ("cols: %u indx: %u fks: %u", columns.length (), indexes.length (), fks.length ());
+
+ // table_names.foreach ((tbname) => {
+ // var table = new Table (schema) {
+ // name = tbname,
+ // };
+ // table_groups.insert (tbname, table);
+ // });
+
+ // view_names.foreach ((tbname) => {
+ // var view = new View (schema) {
+ // name = tbname,
+ // };
+ // view_groups.insert (tbname, view);
+ // });
+
+ // columns.foreach ((col) => {
+ // if (table_groups.contains (col.table)) {
+ // var table = table_groups.get (col.table);
+ // table.columns.append (col);
+ // }
+
+ // if (view_groups.contains (col.table)) {
+ // var view = view_groups.get (col.table);
+ // view.columns.append (col);
+ // }
+ // });
+
+ // indexes.foreach ((index) => {
+ // if (table_groups.contains (index.table)) {
+ // var table = table_groups.get (index.table);
+ // table.indexes.append (index);
+ // }
+
+ // if (view_groups.contains (index.table)) {
+ // var view = view_groups.get (index.table);
+ // view.indexes.append (index);
+ // }
+ // });
+
+ // fks.foreach ((fk) => {
+ // if (table_groups.contains (fk.table)) {
+ // var table = table_groups.get (fk.table);
+ // table.foreign_keys.append (fk);
+ // }
+ // });
+
+ // var tables = table_groups.steal_all_values ();
+
+ // for (int i = 0; i < tables.length; i++) {
+ // schema.tables.append (tables[i]);
+ // }
+
+ // var views = view_groups.steal_all_values ();
+
+ // for (int i = 0; i < views.length; i++) {
+ // schema.views.append (views[i]);
+ // }
+ // }
private async List get_tbnames (Schema schema) {
var list = new List ();
try {
- var query = new Query.with_params (TB_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (TB_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -191,7 +191,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (VIEW_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (VIEW_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -209,7 +209,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (COLUMN_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (COLUMN_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -235,7 +235,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (INDEX_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (INDEX_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -260,7 +260,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (FK_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (FK_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
diff --git a/src/ui/PreferencesWindow.vala b/src/ui/PreferencesWindow.vala
index df1f340..1d7e904 100644
--- a/src/ui/PreferencesWindow.vala
+++ b/src/ui/PreferencesWindow.vala
@@ -12,7 +12,6 @@ namespace Psequel {
}
construct {
- debug ("[CONTRUCT] %s", this.name);
setup_binding ();
defaults ();
}
@@ -43,16 +42,11 @@ namespace Psequel {
[GtkCallback]
private void on_font_chooser (Adw.ActionRow row) {
- old_choser ();
- // new_choser ();
- }
-
- private void old_choser () {
- // Create dialog
var dialog = new Gtk.FontChooserDialog (_("Select font"), this) {
modal = true,
transient_for = this,
level = Gtk.FontChooserLevel.FAMILY | Gtk.FontChooserLevel.SIZE | Gtk.FontChooserLevel.STYLE,
+ font = Application.settings.get_string ("editor-font"),
};
dialog.set_filter_func ((desc) => {
@@ -69,14 +63,15 @@ namespace Psequel {
Application.settings.set_string ("editor-font", dialog.font_desc.to_string ());
}
- dialog.close ();
+ dialog.destroy ();
});
/* Show dialog */
- dialog.present ();
+ dialog.show ();
}
+
// private void new_choser () {
// var dialog = new Gtk.FontDialog () {
// modal = true,
diff --git a/src/ui/schema/QueryEditor.vala b/src/ui/schema/QueryEditor.vala
index bf91f1e..92d966f 100644
--- a/src/ui/schema/QueryEditor.vala
+++ b/src/ui/schema/QueryEditor.vala
@@ -6,10 +6,12 @@ namespace Psequel {
public class QueryEditor : Adw.Bin {
- const string TAG_NAME = "query-block";
+ const string LIGHT_TAG = "query-block-light";
+ const string DARK_TAG = "query-block-dark";
delegate void ChangeStateFunc (SimpleAction action, Variant? new_state);
+ public ExportService export_service {get; set;}
public QueryViewModel query_viewmodel { get; set; }
@@ -31,6 +33,7 @@ namespace Psequel {
construct {
debug ("[CONTRUCT] %s", this.name);
+ this.export_service = autowire ();
this.query_viewmodel = autowire ();
this.query_history_viewmodel = autowire ();
@@ -46,50 +49,6 @@ namespace Psequel {
}
- private void highlight_current_query () {
-
- var stmts = PGQuery.split_statement (buffer.text);
-
- // return;
-
- this.clear_highlight ();
- stmts.foreach ((token) => {
-
- var start = token.location;
- var end = token.location + token.statement.length;
-
- // debug ("[%d, %d], %s", token.location, token.end, token.value);
-
- Gtk.TextIter iter1;
- Gtk.TextIter iter2;
-
- // buffer.get_start_iter (out iter1);
- // buffer.get_end_iter (out iter2);
- // buffer.remove_tag_by_name (TAG_NAME, iter1, iter2);
-
- buffer.get_iter_at_offset (out iter1, start);
- buffer.get_iter_at_offset (out iter2, end);
-
- if (start < buffer.cursor_position && buffer.cursor_position <= end + 1) {
- buffer.apply_tag_by_name (TAG_NAME, iter1, iter2);
-
- // Important
- query_viewmodel.selected_query_changed (token.statement);
- } else {
- buffer.remove_tag_by_name (TAG_NAME, iter1, iter2);
- }
- });
- }
-
- private inline void clear_highlight () {
- Gtk.TextIter start;
- Gtk.TextIter end;
-
- buffer.get_start_iter (out start);
- buffer.get_end_iter (out end);
- buffer.remove_tag_by_name (TAG_NAME, start, end);
- }
-
[GtkCallback]
private void run_query_cb (Gtk.Button btn) {
query_viewmodel.run_selected_query.begin ();
@@ -104,12 +63,18 @@ namespace Psequel {
[GtkCallback]
private void on_query_history_exec (Gtk.ListView view, uint pos) {
- query_history_viewmodel.exec_history.begin (selected_query);
+ var history_query = (Query)selection_model.get_item (pos);
- var text = selected_query == null ? "" : selected_query.sql;
- clear_and_insert (buffer, text);
+ debug ("%p", history_query);
+ debug ("%u", selection_model.get_n_items ());
+ debug ("%u %i", pos, query_history_viewmodel.query_history.size);
+ // debug ("History activated, exec: %s", history_query.sql);
+ // query_history_viewmodel.exec_history.begin (history_query);
- popover.hide ();
+ // var text = history_query.sql ?? "";
+ // clear_and_insert (buffer, text);
+
+ // popover.hide ();
}
/** Clear and insert insteal of manipulate .text to keep undo possible */
@@ -140,14 +105,18 @@ namespace Psequel {
var lang = lang_manager.get_language ("sql");
buffer.language = lang;
- var tag = new Gtk.TextTag (TAG_NAME);
+ // rgba(104, 109, 224,1.0)
+ var light_tag = new Gtk.TextTag (LIGHT_TAG);
+ light_tag.background_rgba = { 237 / 255f, 255 / 255f, 255 / 255f, 0.9f };
+
+ // rgba(149, 175, 192,1.0)
+ var dark_tag = new Gtk.TextTag (DARK_TAG);
+ dark_tag.background_rgba = { 149 / 255f, 175 / 255f, 192 / 255f, 0.2f };
// tag.background = "sidebar_backdrop_color";
// rgba(52, 73, 94,1.0)
- tag.background_rgba = { 52 / 255f, 73 / 255f, 94 / 255f, 0.3f };
- buffer.tag_table.add (tag);
-
-
-
+ // rgb(237, 255, 255)
+ buffer.tag_table.add (light_tag);
+ buffer.tag_table.add (dark_tag);
Application.app.style_manager.bind_property ("dark", buffer, "style_scheme", BindingFlags.SYNC_CREATE, (binding, from, ref to) => {
var is_dark = from.get_boolean ();
@@ -163,6 +132,61 @@ namespace Psequel {
});
}
+ private void highlight_current_query () {
+
+ var stmts = PGQuery.split_statement (buffer.text);
+ this.clear_highlight ();
+ stmts.foreach ((token) => {
+
+ var start = token.location;
+ var end = token.location + token.statement.length;
+
+ // debug ("[%d, %d], %s", token.location, token.end, token.value);
+
+ Gtk.TextIter iter1;
+ Gtk.TextIter iter2;
+
+ // buffer.get_start_iter (out iter1);
+ // buffer.get_end_iter (out iter2);
+ // buffer.remove_tag_by_name (TAG_NAME, iter1, iter2);
+
+ buffer.get_iter_at_offset (out iter1, start);
+ buffer.get_iter_at_offset (out iter2, end);
+
+ if (start < buffer.cursor_position && buffer.cursor_position <= end + 1) {
+
+ // Double-check with strict mode.
+ string statement = buffer.get_text (iter1, iter2, false);
+ if (PGQuery.split_statement (statement, true) == null) {
+ return;
+ }
+
+
+ if (Application.app.style_manager.dark) {
+ buffer.apply_tag_by_name (DARK_TAG, iter1, iter2);
+ } else {
+ buffer.apply_tag_by_name (LIGHT_TAG, iter1, iter2);
+ }
+
+ // Important
+ query_viewmodel.selected_query_changed (token.statement);
+ } else {
+ buffer.remove_tag_by_name (DARK_TAG, iter1, iter2);
+ buffer.remove_tag_by_name (LIGHT_TAG, iter1, iter2);
+ }
+ });
+ }
+
+ private inline void clear_highlight () {
+ Gtk.TextIter start;
+ Gtk.TextIter end;
+
+ buffer.get_start_iter (out start);
+ buffer.get_end_iter (out end);
+ buffer.remove_tag_by_name (DARK_TAG, start, end);
+ buffer.remove_tag_by_name (LIGHT_TAG, start, end);
+ }
+
private void create_action_group () {
var group = new SimpleActionGroup ();
@@ -237,6 +261,43 @@ namespace Psequel {
return true;
}
+ [GtkCallback]
+ private void on_export_csv (Gtk.Button btn) {
+ export_to_csv_file.begin ();
+ }
+
+ private async void export_to_csv_file (string title = "Open File") {
+ var filter = new Gtk.FileFilter ();
+ // filter.add_pattern ("*.csv");
+ filter.add_mime_type ("text/csv");
+ var filters = new ListStore (typeof (Gtk.FileFilter));
+ filters.append (filter);
+
+ var window = (Window) get_parrent_window (this);
+
+ var file_dialog = new Gtk.FileDialog () {
+ modal = true,
+ initial_folder = GLib.File.new_for_path (Environment.get_home_dir ()),
+ title = title,
+ default_filter = filter,
+ filters = filters
+ };
+
+ try {
+ var dest = yield file_dialog.save (window, null);
+ yield export_service.export_csv (dest, query_history_viewmodel.current_relation);
+
+ } catch (GLib.Error err) {
+ debug (err.message);
+
+ var toast = new Adw.Toast (err.message) {
+ timeout = 3,
+ };
+
+ window.add_toast (toast);
+ }
+ }
+
[GtkChild]
private unowned GtkSource.View editor;
diff --git a/src/utils/errors.vala b/src/utils/errors.vala
index 565234c..a9c27d0 100644
--- a/src/utils/errors.vala
+++ b/src/utils/errors.vala
@@ -2,6 +2,7 @@ namespace Psequel {
public errordomain PsequelError {
CONNECTION_ERROR,
QUERY_FAIL,
- PARSE_ERROR
+ PARSE_ERROR,
+ EXPORT_ERROR
}
}
\ No newline at end of file
diff --git a/src/viewmodels/BaseViewModel.vala b/src/viewmodels/BaseViewModel.vala
index 1d83dfc..89144f3 100644
--- a/src/viewmodels/BaseViewModel.vala
+++ b/src/viewmodels/BaseViewModel.vala
@@ -18,6 +18,7 @@ namespace Psequel {
}
protected void emit_event(string event_type, Object data) {
+ debug ("Emit: %s", event_type);
event_manager.notify (event_type, data);
}
}
diff --git a/src/viewmodels/QueryHistoryViewModel.vala b/src/viewmodels/QueryHistoryViewModel.vala
index 7882716..553199d 100644
--- a/src/viewmodels/QueryHistoryViewModel.vala
+++ b/src/viewmodels/QueryHistoryViewModel.vala
@@ -32,12 +32,12 @@ namespace Psequel {
if (current_relation.fetch_time / SECOND_TO_MS > 0) {
if (current_relation.fetch_time / SECOND_TO_MS / MILISECS_TO_US > 0) {
- query_time = @"Exec time: $(current_relation.fetch_time / SECOND_TO_MS / MILISECS_TO_US) s";
+ query_time = @"$(current_relation.fetch_time / SECOND_TO_MS / MILISECS_TO_US) s";
} else {
- query_time = @"Exec time: $(current_relation.fetch_time / SECOND_TO_MS) ms";
+ query_time = @"$(current_relation.fetch_time / SECOND_TO_MS) ms";
}
} else {
- query_time = @"Exec time: $(current_relation.fetch_time) μs";
+ query_time = @"$(current_relation.fetch_time) μs";
}
});
}
diff --git a/src/viewmodels/SchemaViewModel.vala b/src/viewmodels/SchemaViewModel.vala
index e3f7f63..2f17668 100644
--- a/src/viewmodels/SchemaViewModel.vala
+++ b/src/viewmodels/SchemaViewModel.vala
@@ -17,50 +17,49 @@ namespace Psequel {
this.schema_service = service;
this.notify["current-schema"].connect (() => {
- debug ("emit SCHEMA_CHANGED");
this.emit_event (Event.SCHEMA_CHANGED, current_schema);
});
}
+ public void select_index (int index) {
+ if (index < 0 || index >= schemas.size) {
+ return;
+ }
+ select_schema.begin (schemas[index]);
+ }
+
public void update (Event event) {
if (event.type == Event.ACTIVE_CONNECTION) {
database_connected.begin ();
}
}
- public async void database_connected () throws PsequelError {
+ public async void reload () throws PsequelError {
+ if (current_schema == null) {
+ return;
+ }
+ yield select_schema (current_schema);
+ }
+
+ private async void database_connected () throws PsequelError {
// auto load schema list.
yield list_schemas ();
- yield load_schema (schemas.find (s => s.name == DEFAULT));
+ yield select_schema (schemas.find (s => s.name == DEFAULT));
}
- public async void load_schema (Schema schema) throws PsequelError {
- debug ("Loading schema: %s", schema.name);
+ /** Select current schema */
+ private async void select_schema (Schema schema) throws PsequelError {
+ debug ("Select schema: %s", schema.name);
current_schema = schema;
-
// force reload
this.notify_property ("current-schema");
}
- public async void reload () throws PsequelError {
- if (current_schema == null) {
- return;
- }
- yield load_schema (current_schema);
- }
-
- public async void list_schemas () throws PsequelError {
+ /** List schema from database. */
+ private async void list_schemas () throws PsequelError {
var unload_schemas = yield schema_service.get_schemas ();
schemas.append_all (unload_schemas);
}
-
- public void select_index (int index) {
- if (index < 0 || index >= schemas.size) {
- return;
- }
- debug ("Selecting schema: %s", schemas[index].name);
- current_schema = schemas[index];
- }
}
}
\ No newline at end of file
diff --git a/src/viewmodels/TableStructureViewModel.vala b/src/viewmodels/TableStructureViewModel.vala
index ff2bd3c..8d31311 100644
--- a/src/viewmodels/TableStructureViewModel.vala
+++ b/src/viewmodels/TableStructureViewModel.vala
@@ -49,7 +49,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (COLUMN_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (COLUMN_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -75,7 +75,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (INDEX_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (INDEX_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -100,7 +100,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (FK_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (FK_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
diff --git a/src/viewmodels/TableViewModel.vala b/src/viewmodels/TableViewModel.vala
index 935ba57..a0c8871 100644
--- a/src/viewmodels/TableViewModel.vala
+++ b/src/viewmodels/TableViewModel.vala
@@ -5,9 +5,6 @@ namespace Psequel {
public ObservableList tables { get; set; default = new ObservableList (); }
public Table? selected_table { get; set; }
- public TableDataViewModel tabledata_viewmodel { get; set; }
- public TableStructureViewModel tablestructure_viewmodel {get; set;}
-
public SQLService sql_service {get; private set;}
diff --git a/src/viewmodels/ViewStructureViewModel.vala b/src/viewmodels/ViewStructureViewModel.vala
index 9f2a19e..059f172 100644
--- a/src/viewmodels/ViewStructureViewModel.vala
+++ b/src/viewmodels/ViewStructureViewModel.vala
@@ -44,7 +44,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (COLUMN_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (COLUMN_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
@@ -70,7 +70,7 @@ namespace Psequel {
var list = new List ();
try {
- var query = new Query.with_params (INDEX_SQL, { new Variant.string (schema.name) });
+ var query = new Query.with_params (INDEX_SQL, { schema.name });
var relation = yield sql_service.exec_query_params (query);
foreach (var row in relation) {
diff --git a/src/viewmodels/ViewViewModel.vala b/src/viewmodels/ViewViewModel.vala
index 5347cb4..5d6a227 100644
--- a/src/viewmodels/ViewViewModel.vala
+++ b/src/viewmodels/ViewViewModel.vala
@@ -5,13 +5,9 @@ namespace Psequel {
public ObservableList views { get; set; default = new ObservableList (); }
public View? selected_view { get; set; }
-
public Schema schema { get; private set; }
public SQLService sql_service { get; private set; }
- public ViewStructureViewModel viewstructure_viewmodel {get; set;}
- public ViewDataViewModel viewdata_viewmodel {get; set;}
-
public ViewViewModel (SQLService service) {
base();
@@ -29,7 +25,7 @@ namespace Psequel {
}
}
- public void select_view (View view) {
+ public void select_view (View? view) {
if (view == null) {
return;
}