diff --git a/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java b/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java index c6fe4085d..34cdbbde0 100644 --- a/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/Xoax_addon_mgr.java @@ -72,6 +72,7 @@ public class Xoax_addon_mgr { , new gplx.xowa.addons.wikis.directorys .Xowdir_addon() , new gplx.xowa.addons.apps.cfgs .Xoa_cfg_addon() , new gplx.xowa.addons.apps.updates .Xoa_update_addon() + , new gplx.xowa.addons.apps.maints.sql_execs .Xosql_exec_addon() // jsons ); diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/Xosql_exec_addon.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/Xosql_exec_addon.java new file mode 100644 index 000000000..398d28e8f --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/Xosql_exec_addon.java @@ -0,0 +1,33 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; +import gplx.xowa.specials.*; import gplx.xowa.htmls.bridges.*; +public class Xosql_exec_addon implements Xoax_addon_itm, Xoax_addon_itm__special, Xoax_addon_itm__json { + public Xow_special_page[] Special_pages() { + return new Xow_special_page[] + { gplx.xowa.addons.apps.maints.sql_execs.specials.Xosql_exec_special.Prototype + }; + } + public Bridge_cmd_itm[] Json_cmds() { + return new Bridge_cmd_itm[] + { gplx.xowa.addons.apps.maints.sql_execs.cbks.Xosql_exec_bridge.Prototype + }; + } + + public String Addon__key() {return ADDON__KEY;} private static final String ADDON__KEY = "xowa.app.maint.sql_exec"; +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_bridge.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_bridge.java new file mode 100644 index 000000000..b3da8f403 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_bridge.java @@ -0,0 +1,43 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs.cbks; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; import gplx.xowa.addons.apps.maints.sql_execs.*; +import gplx.langs.jsons.*; +import gplx.xowa.htmls.bridges.*; +public class Xosql_exec_bridge implements Bridge_cmd_itm { + private Xosql_exec_svc svc; + public void Init_by_app(Xoa_app app) { + this.svc = new Xosql_exec_svc(app); + } + public String Exec(Json_nde data) { + byte proc_id = proc_hash.Get_as_byte_or(data.Get_as_bry_or(Bridge_cmd_mgr.Msg__proc, null), Byte_ascii.Max_7_bit); + Json_nde args = data.Get_kv(Bridge_cmd_mgr.Msg__args).Val_as_nde(); + switch (proc_id) { + case Proc__exec: svc.Exec(args); break; + default: throw Err_.new_unhandled_default(proc_id); + } + return ""; + } + + private static final byte Proc__exec = 0; + private static final Hash_adp_bry proc_hash = Hash_adp_bry.cs() + .Add_str_byte("exec" , Proc__exec) + ; + + public byte[] Key() {return BRIDGE_KEY;} public static final byte[] BRIDGE_KEY = Bry_.new_a7("xowa.app.maint.sql_exec"); + public static final Xosql_exec_bridge Prototype = new Xosql_exec_bridge(); Xosql_exec_bridge() {} +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_svc.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_svc.java new file mode 100644 index 000000000..d05ba2f53 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/cbks/Xosql_exec_svc.java @@ -0,0 +1,92 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs.cbks; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; import gplx.xowa.addons.apps.maints.sql_execs.*; +import gplx.langs.jsons.*; +import gplx.dbs.*; import gplx.xowa.specials.xowa.diags.*; +/* TODO.XO + * add backup function to backup db + * option to output to file + * run multiple SQL statements (need to change jdbc) + * print column headers if SELECT + * print row counts + * run stored procs? EXEC debug_image 'A.png' +*/ +class Xosql_exec_svc { + private gplx.xowa.guis.cbks.Xog_cbk_trg cbk_trg = gplx.xowa.guis.cbks.Xog_cbk_trg.New(gplx.xowa.addons.apps.maints.sql_execs.specials.Xosql_exec_special.Prototype.Special__meta().Ttl_bry()); + private final Xoa_app app; + public Xosql_exec_svc(Xoa_app app) { + this.app = app; + } + public void Exec(Json_nde args) { + String domain = args.Get_as_str("domain"); + String db = args.Get_as_str("db"); + String sql = args.Get_as_str("sql"); + + // get conn + Db_conn conn = null; + if (String_.Eq(domain, DOMAIN__APP)) { + if (String_.Eq(db, DB__USER)) { + conn = app.User().User_db_mgr().Conn(); + } + } + else if (String_.Eq(domain, DOMAIN__FILE)) { + conn = Db_conn_bldr.Instance.Get_or_fail(Io_url_.new_any_(db)); + } + else { + Xow_wiki wiki = String_.Eq(domain, DOMAIN__HOME) + ? wiki = app.User().Wikii() + : app.Wiki_mgri().Get_by_or_make_init_y(Bry_.new_u8(domain)); + + // for now, only support core + if (String_.Eq(db, DB__CORE)) { + conn = wiki.Data__core_mgr().Db__core().Conn(); + } + } + + String results = null; + try { + // run sql + // HACK: assume SQL starting with SELECT is a reader + if (String_.Has_at_bgn(sql, "SELECT ")) { + // run select + Bry_bfr bfr = Bry_bfr_.New(); + Object[][] rows = Db_rdr_utl.Load(conn, sql); + Db_rdr_utl.Write_to_bfr(bfr, rows); + results = bfr.To_str_and_clear(); + } + else { + conn.Exec_sql(sql); + results = "executed"; + } + } catch (Exception exc) { + results = Err_.Message_gplx_full(exc); + results = String_.Replace(results, "\t", "    "); // tabs must be escaped, else "bad character in String literal" + } + + // send results + app.Gui__cbk_mgr().Send_json(cbk_trg, "xo.sql_exec.results__recv", gplx.core.gfobjs.Gfobj_nde.New() + .Add_bry("msg_text", Bry_.Escape_html(Bry_.new_u8(results)))); // escape html; EX: "<" -> "<" + } + private static final String + DOMAIN__APP = "[xowa.app]" + , DOMAIN__HOME = "[xowa.home]" + , DOMAIN__FILE = "[file]" + , DB__CORE = "core" + , DB__USER = "user" + ; +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_doc.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_doc.java new file mode 100644 index 000000000..bf97c79e8 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_doc.java @@ -0,0 +1,39 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; import gplx.xowa.addons.apps.maints.sql_execs.*; +import gplx.langs.mustaches.*; +public class Xosql_exec_doc implements Mustache_doc_itm { + private final String domain, db, sql; + public Xosql_exec_doc(String domain, String db, String sql) { + this.domain = domain; + this.db = db; + this.sql = sql; + } + public boolean Mustache__write(String key, Mustache_bfr bfr) { + if (String_.Eq(key, "domain")) bfr.Add_str_u8(domain); + else if (String_.Eq(key, "db")) bfr.Add_str_u8(db); + else if (String_.Eq(key, "sql")) bfr.Add_str_u8(sql); + else return false; + return true; + } + public Mustache_doc_itm[] Mustache__subs(String key) { + return Mustache_doc_itm_.Ary__empty; + } + + public static final Xosql_exec_doc[] Ary_empty = new Xosql_exec_doc[0]; +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_html.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_html.java new file mode 100644 index 000000000..011a3518f --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_html.java @@ -0,0 +1,49 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; import gplx.xowa.addons.apps.maints.sql_execs.*; +import gplx.xowa.specials.*; import gplx.langs.mustaches.*; import gplx.xowa.wikis.pages.*; import gplx.xowa.wikis.pages.tags.*; +import gplx.dbs.*; +class Xosql_exec_html extends Xow_special_wtr__base { + private final String domain, db, sql; + public Xosql_exec_html(String domain, String db, String sql) { + this.domain = domain; + this.db = db; + this.sql = sql; + } + @Override protected Io_url Get_addon_dir(Xoa_app app) {return Addon_dir(app);} + @Override protected Io_url Get_mustache_fil(Io_url addon_dir) {return addon_dir.GenSubFil_nest("bin", "xosql_exec.template.html");} + @Override protected Mustache_doc_itm Bld_mustache_root(Xoa_app app) { + return new Xosql_exec_doc(domain, db, sql); + } + @Override protected void Bld_tags(Xoa_app app, Io_url addon_dir, Xopage_html_data page_data) { + Xopg_tag_mgr head_tags = page_data.Head_tags(); + Xopg_tag_wtr_.Add__xocss (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xohelp (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xolog (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xoajax (head_tags, app.Fsys_mgr().Http_root(), app); + Xopg_tag_wtr_.Add__jquery (head_tags, app.Fsys_mgr().Http_root()); + Xopg_tag_wtr_.Add__xonotify (head_tags, app.Fsys_mgr().Http_root()); + Xopg_alertify_.Add_tags (head_tags, app.Fsys_mgr().Http_root()); + + head_tags.Add(Xopg_tag_itm.New_css_file(addon_dir.GenSubFil_nest("bin", "xosql_exec.css"))); + head_tags.Add(Xopg_tag_itm.New_js_file(addon_dir.GenSubFil_nest("bin", "xosql_exec.js"))); + } + public static Io_url Addon_dir(Xoa_app app) { + return app.Fsys_mgr().Http_root().GenSubDir_nest("bin", "any", "xowa", "addon", "app", "maint", "sql_exec"); + } +} diff --git a/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_special.java b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_special.java new file mode 100644 index 000000000..b51504ad0 --- /dev/null +++ b/400_xowa/src/gplx/xowa/addons/apps/maints/sql_execs/specials/Xosql_exec_special.java @@ -0,0 +1,34 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012 gnosygnu@gmail.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . +*/ +package gplx.xowa.addons.apps.maints.sql_execs.specials; import gplx.*; import gplx.xowa.*; import gplx.xowa.addons.*; import gplx.xowa.addons.apps.*; import gplx.xowa.addons.apps.maints.*; import gplx.xowa.addons.apps.maints.sql_execs.*; +import gplx.xowa.specials.*; import gplx.core.net.qargs.*; +public class Xosql_exec_special implements Xow_special_page { + public void Special__gen(Xow_wiki wiki, Xoa_page page, Xoa_url url, Xoa_ttl ttl) { + Gfo_qarg_mgr url_args = new Gfo_qarg_mgr().Init(url.Qargs_ary()); + + String domain = url_args.Read_str_or("domain", "[xowa.home]"); + String db = url_args.Read_str_or("db", "core"); + String sql = url_args.Read_str_or("sql", "SELECT * FROM xowa_cfg;"); + + new Xosql_exec_html(domain, db, sql).Bld_page_by_mustache(wiki.App(), page, this); + } + Xosql_exec_special(Xow_special_meta special__meta) {this.special__meta = special__meta;} + public Xow_special_meta Special__meta() {return special__meta;} private final Xow_special_meta special__meta; + public Xow_special_page Special__clone() {return this;} + public static final Xow_special_page Prototype = new Xosql_exec_special(Xow_special_meta.New_xo("XowaSqlExec", "SQL Exec", "XowaSql")); +} diff --git a/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java b/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java index 7fc48accd..fd79bf1e7 100644 --- a/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java +++ b/400_xowa/src/gplx/xowa/specials/xowa/diags/Db_rdr_utl.java @@ -19,7 +19,7 @@ package gplx.xowa.specials.xowa.diags; import gplx.*; import gplx.xowa.*; import import gplx.core.stores.*; import gplx.dbs.*; import gplx.dbs.engines.mems.*; -class Db_rdr_utl { +public class Db_rdr_utl { public static void Load_and_write(Db_conn conn, String sql, Bry_bfr bfr) { Write_to_bfr(bfr, Load(conn, sql)); }